diff --git a/README.md b/README.md index 8cb4c1f2..0a2f3892 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,6 @@ let fdkClient = setupFdk({ api_key: "", api_secret: "", base_url: baseUrl, // this is optional - scopes: ["company/products"], // this is optional callbacks: extensionHandler, storage: new RedisStorage(redis), access_mode: "offline", @@ -137,7 +136,6 @@ let fdkClient = setupFdk({ api_key: "", api_secret: "", base_url: baseUrl, // this is optional - scopes: ["company/products"], // this is optional callbacks: { auth: async function (data) { console.log("called auth callback"); diff --git a/examples/test.js b/examples/test.js index 46d37efa..231689fa 100644 --- a/examples/test.js +++ b/examples/test.js @@ -50,7 +50,6 @@ let fdkExtension = setupFdk({ api_key: "6220daa4a5414621b975a41f", api_secret: "EbeGBRC~Fthv5om", base_url: baseUrl, // this is optional - scopes: ["company/product"], // this is optional callbacks: extensionHandler, storage: new RedisStorage(redis), access_mode: "offline", diff --git a/express/extension.js b/express/extension.js index 4a8cf357..173e4038 100644 --- a/express/extension.js +++ b/express/extension.js @@ -72,11 +72,6 @@ class Extension { } this.base_url = data.base_url; - if (data.scopes) { - data.scopes = this.verifyScopes(data.scopes, this.extensionData); - } - this.scopes = data.scopes || this.extensionData.scope; - logger.debug(`Extension initialized`); if (data.webhook_config && Object.keys(data.webhook_config)) { @@ -90,14 +85,6 @@ class Extension { return this._isInitialized; } - verifyScopes(scopes, extensionData) { - const missingScopes = scopes.filter(val => extensionData.scope.indexOf(val) === -1); - if (!scopes || scopes.length <= 0 || missingScopes.length) { - throw new FdkInvalidExtensionConfig("Invalid scopes in extension config. Invalid scopes: " + missingScopes.join(", ")); - } - return scopes; - } - getAuthCallback() { return urljoin(this.base_url, "/fp/auth"); } diff --git a/express/routes.js b/express/routes.js index 6d7e0f0c..8eaae6b5 100644 --- a/express/routes.js +++ b/express/routes.js @@ -16,21 +16,26 @@ function setupRoutes(ext) { let storage = ext.storage; let callbacks = ext.callbacks; - FdkRoutes.get("/fp/install", async (req, res, next) => { + FdkRoutes.get("/fp/install", sessionMiddleware(false), async (req, res, next) => { // ?company_id=1&client_id=123313112122 try { let companyId = parseInt(req.query.company_id); let platformConfig = await ext.getPlatformConfig(companyId); let session; let redirectPath = req.query.redirect_path; + let isAuthenticated = false; + if (req.fdkSession?.isSessionValid()) { + isAuthenticated = true; + } + else { session = new Session(Session.generateSessionId(true)); let sessionExpires = new Date(Date.now() + 900000); // 15 min if (session.isNew) { session.company_id = companyId; - session.scope = ext.scopes; + session.scope = ext.scopes; session.expires = sessionExpires; session.access_mode = 'online'; // Always generate online mode token for extension launch session.extension_id = ext.api_key; @@ -40,8 +45,10 @@ function setupRoutes(ext) { session.expires = new Date(session.expires); } } - req.fdkSession = session; + } + + req.extension = ext; const compCookieName = `${SESSION_COOKIE_NAME}_${companyId}` @@ -67,10 +74,10 @@ function setupRoutes(ext) { // start authorization flow redirectUrl = platformConfig.oauthClient.startAuthorization({ - scope: session.scope, + scope: null, redirectUri: authCallback, state: session.state, - access_mode: 'online' // Always generate online mode token for extension launch + access_mode: !isAuthenticated? 'online': 'offline' // Always generate online mode token for extension launch }); await SessionStorage.saveSession(session); logger.debug(`Redirecting after install callback to url: ${redirectUrl}`); @@ -93,16 +100,22 @@ function setupRoutes(ext) { const companyId = req.fdkSession.company_id const platformConfig = await ext.getPlatformConfig(req.fdkSession.company_id); + + let sessionExpires; + + if (!req.fdkSession.isSessionValid()) { + await platformConfig.oauthClient.verifyCallback(req.query); let token = platformConfig.oauthClient.raw_token; - let sessionExpires = new Date(Date.now() + token.expires_in * 1000); + sessionExpires = new Date(Date.now() + token.expires_in * 1000); req.fdkSession.expires = sessionExpires; token.access_token_validity = sessionExpires.getTime(); req.fdkSession.updateToken(token); - await SessionStorage.saveSession(req.fdkSession); + } + // Generate separate access token for offline mode if (!ext.isOnlineAccessMode()) { @@ -118,10 +131,9 @@ function setupRoutes(ext) { session = new Session(sid); } - let offlineTokenRes = await platformConfig.oauthClient.getOfflineAccessToken(ext.scopes, req.query.code); + let offlineTokenRes = await platformConfig.oauthClient.getOfflineAccessToken(null, req.query.code); session.company_id = companyId; - session.scope = ext.scopes; session.state = req.fdkSession.state; session.extension_id = ext.api_key; offlineTokenRes.access_token_validity = platformConfig.oauthClient.token_expires_at; @@ -182,7 +194,7 @@ function setupRoutes(ext) { session = new Session(sid); } - let offlineTokenRes = await platformConfig.oauthClient.getOfflineAccessToken(ext.scopes, code); + let offlineTokenRes = await platformConfig.oauthClient.getOfflineAccessToken(null, code); session.company_id = company_id; session.scope = ext.scopes; @@ -244,7 +256,6 @@ function setupRoutes(ext) { if (session.isNew) { session.organization_id = organizationId; - session.scope = ext.scopes; session.expires = sessionExpires; session.access_mode = 'online'; session.extension_id = ext.api_key; @@ -272,7 +283,7 @@ function setupRoutes(ext) { let authCallback = urljoin(ext.base_url, "/adm/auth"); let redirectUrl = partnerConfig.oauthClient.startAuthorization({ - scope: session.scope, + scope: null, redirectUri: authCallback, state: session.state, access_mode: 'online' @@ -327,10 +338,9 @@ function setupRoutes(ext) { session = new Session(sid); } - let offlineTokenRes = await partnerConfig.oauthClient.getOfflineAccessToken(ext.scopes, req.query.code); + let offlineTokenRes = await partnerConfig.oauthClient.getOfflineAccessToken(null, req.query.code); session.organization_id = organizationId; - session.scope = ext.scopes; session.state = req.fdkSession.state; session.extension_id = ext.api_key; offlineTokenRes.access_token_validity = partnerConfig.oauthClient.token_expires_at; diff --git a/express/session/session.js b/express/session/session.js index c12cffa5..fb6fd2db 100644 --- a/express/session/session.js +++ b/express/session/session.js @@ -54,6 +54,12 @@ class Session { this.access_token_validity = rawToken.access_token_validity } + // Verifies if token is already generated and it is valid + isSessionValid() { + const currentTimestamp = (new Date()).getTime(); + return this.access_token && this.access_token_validity < currentTimestamp; + } + static generateSessionId(isOnline, options) { if(isOnline) { return v4(); diff --git a/spec/helpers/fdk.js b/spec/helpers/fdk.js index 6a664057..8fcf4fc8 100644 --- a/spec/helpers/fdk.js +++ b/spec/helpers/fdk.js @@ -7,7 +7,6 @@ module.exports = (settings) => { api_key: "API_KEY", api_secret: "API_SECRET", base_url: "http://localdev.fyndx0.de", - scopes: ["company/products"], callbacks: { auth: ()=>{}, uninstall: ()=>{}