From cb2d483e7fb97037287d8dd9a47f67d35ee0fc4d Mon Sep 17 00:00:00 2001
From: Bastien DUMONT <bdumont@grandlyon.com>
Date: Thu, 8 Aug 2024 12:25:22 +0000
Subject: [PATCH] feat: fetch BO for GRDF access token

---
 konnector-dev-config.example.json |  4 +---
 package.json                      |  3 +--
 src/index.js                      |  9 +++-----
 src/requests/bo.js                | 31 ++++++++++++++++++++++++++
 src/requests/grdf.js              | 37 +------------------------------
 yarn.lock                         | 33 +++++++++++++++++++++++----
 6 files changed, 66 insertions(+), 51 deletions(-)

diff --git a/konnector-dev-config.example.json b/konnector-dev-config.example.json
index 9286f6a..ba21588 100644
--- a/konnector-dev-config.example.json
+++ b/konnector-dev-config.example.json
@@ -10,9 +10,7 @@
   "COZY_PARAMETERS": {
     "secret": {
       "boBaseUrl": "",
-      "boToken": "",
-      "client_id": "",
-      "client_secret": ""
+      "boToken": ""
     }
   }
 }
diff --git a/package.json b/package.json
index 81a5181..7c166d4 100755
--- a/package.json
+++ b/package.json
@@ -44,8 +44,7 @@
     "cozy-client": "48.7.0",
     "cozy-konnector-libs": "5.11.0",
     "moment": "^2.30.1",
-    "moment-timezone": "^0.5.45",
-    "qs": "^6.12.1"
+    "moment-timezone": "^0.5.45"
   },
   "devDependencies": {
     "cozy-jobs-cli": "2.4.2",
diff --git a/src/index.js b/src/index.js
index f951677..0936039 100755
--- a/src/index.js
+++ b/src/index.js
@@ -13,7 +13,7 @@ require('moment-timezone')
 moment.locale('fr') // set the language
 moment.tz.setDefault('Europe/Paris') // set the timezone
 const Sentry = require('@sentry/node')
-const { getAuthToken, getConsents } = require('./requests/grdf')
+const { getConsents } = require('./requests/grdf')
 const { handleConsents, createConsent } = require('./core/core')
 const { rangeDate } = require('./constants')
 const {
@@ -23,6 +23,7 @@ const {
   filterFirstYearlyLoad,
 } = require('./helpers/utils')
 const { formatData } = require('./helpers/format')
+const { getGRDFAccessToken } = require('./requests/bo.js')
 
 const NO_DATA = process.env.NO_DATA === 'true'
 const manualExecution = process.env.COZY_JOB_MANUAL_EXECUTION === 'true'
@@ -65,15 +66,11 @@ async function start(fields, cozyParameters) {
 
   let boToken = ''
   let boBaseUrl = ''
-  let grdfId = ''
-  let grdfSecret = ''
 
   if (cozyParameters && Object.keys(cozyParameters).length !== 0) {
     log('debug', 'Found COZY_PARAMETERS')
     boToken = cozyParameters.secret.boToken
     boBaseUrl = cozyParameters.secret.boBaseUrl
-    grdfId = cozyParameters.secret.client_id
-    grdfSecret = cozyParameters.secret.client_secret
   }
   const boUrlGRDF = new URL('/api/grdf', boBaseUrl).href
 
@@ -83,7 +80,7 @@ async function start(fields, cozyParameters) {
       throw errors.USER_ACTION_NEEDED
     }
     log('info', `using PCE: ${pce}`)
-    const { access_token } = await getAuthToken(grdfId, grdfSecret)
+    const { access_token } = await getGRDFAccessToken(boUrlGRDF, boToken)
     const consents = await getConsents(access_token, pce)
     const noValidConsent = await handleConsents(consents, boUrlGRDF, boToken)
 
diff --git a/src/requests/bo.js b/src/requests/bo.js
index 7df4bd0..5d3e1cc 100644
--- a/src/requests/bo.js
+++ b/src/requests/bo.js
@@ -3,6 +3,36 @@ const { log, errors } = require('cozy-konnector-libs')
 const { default: axios } = require('axios')
 const Sentry = require('@sentry/node')
 
+/**
+ * Fetches the GRDF access token from the back office
+ * @param boUrlGRDF: string,
+ * @param boToken: string,
+ * @returns {Promise<{access_token: string, fetched_at: string}>}
+ */
+async function getGRDFAccessToken(boUrlGRDF, boToken) {
+  log('info', `Query getGRDFAccessToken`)
+
+  const headers = {
+    headers: {
+      Authorization: `Bearer ${boToken}`,
+    },
+  }
+  try {
+    const { data } = await axios.get(`${boUrlGRDF}/access-token`, headers)
+    return data
+  } catch (err) {
+    const errorMessage =
+      'Error while getting GRDF access token : ' + err.message
+    log('error', errorMessage)
+    Sentry.captureException(errorMessage, {
+      tags: {
+        section: 'getGRDFAccessToken',
+      },
+    })
+    throw new Error(errors.MAINTENANCE)
+  }
+}
+
 /**
  * @param {{
  * boUrlGRDF: string,
@@ -94,4 +124,5 @@ async function deleteBoConsent({ boUrlGRDF, boToken, consentId }) {
 module.exports = {
   createBoConsent,
   deleteBoConsent,
+  getGRDFAccessToken,
 }
diff --git a/src/requests/grdf.js b/src/requests/grdf.js
index 9e05c3d..a846716 100644
--- a/src/requests/grdf.js
+++ b/src/requests/grdf.js
@@ -1,43 +1,8 @@
 // @ts-check
 const { default: Axios } = require('axios')
 const { errors, log } = require('cozy-konnector-libs')
-const qs = require('qs')
 const Sentry = require('@sentry/node')
 
-/**
- *
- * @param {string} client_id
- * @param {string} client_secret
- * @returns {Promise<{ access_token: string, scope: string, token_type: string, expires_in: number }>}
- */
-async function getAuthToken(client_id, client_secret) {
-  log('info', 'getAuthToken')
-  const body = {
-    scope: '/adict/v2',
-    grant_type: 'client_credentials',
-    client_id: client_id,
-    client_secret: client_secret,
-  }
-  try {
-    const response = await Axios({
-      method: 'POST',
-      url: 'https://adict-connexion.grdf.fr/oauth2/aus5y2ta2uEHjCWIR417/v1/token',
-      headers: { 'content-type': 'application/x-www-form-urlencoded' },
-      data: qs.stringify(body),
-    })
-
-    return response.data
-  } catch (error) {
-    log('error', 'Error inside getAuthToken', error)
-    Sentry.captureException('Error while getting auth token', {
-      tags: {
-        section: 'getAuthToken',
-      },
-    })
-    throw errors.VENDOR_DOWN
-  }
-}
-
 /**
  *
  * @param {string} bearerToken
@@ -127,4 +92,4 @@ async function createGRDFConsent({
   }
 }
 
-module.exports = { createGRDFConsent, getAuthToken, getConsents }
+module.exports = { createGRDFConsent, getConsents }
diff --git a/yarn.lock b/yarn.lock
index 3d5695c..d9dab82 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -7633,7 +7633,7 @@ qs@6.7.0:
   resolved "https://registry.yarnpkg.com/qs/-/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc"
   integrity sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==
 
-qs@^6.12.1, qs@^6.7.0:
+qs@^6.7.0:
   version "6.12.3"
   resolved "https://registry.yarnpkg.com/qs/-/qs-6.12.3.tgz#e43ce03c8521b9c7fd7f1f13e514e5ca37727754"
   integrity sha512-AWJm14H1vVaO/iNZ4/hO+HyaTehuy9nRqVdkTqlJt0HWvBiBIEXFmb4C0DGeYo3Xes9rrEW+TxHsaigCbN5ICQ==
@@ -8423,7 +8423,16 @@ string-length@^4.0.1:
     char-regex "^1.0.2"
     strip-ansi "^6.0.0"
 
-"string-width-cjs@npm:string-width@^4.2.0", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
+"string-width-cjs@npm:string-width@^4.2.0":
+  version "4.2.3"
+  resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
+  integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
+  dependencies:
+    emoji-regex "^8.0.0"
+    is-fullwidth-code-point "^3.0.0"
+    strip-ansi "^6.0.1"
+
+string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
   version "4.2.3"
   resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
   integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
@@ -8511,7 +8520,14 @@ stringify-package@^1.0.1:
   resolved "https://registry.yarnpkg.com/stringify-package/-/stringify-package-1.0.1.tgz#e5aa3643e7f74d0f28628b72f3dad5cecfc3ba85"
   integrity sha512-sa4DUQsYciMP1xhKWGuFM04fB0LG/9DlluZoSVywUMRNvzid6XucHK0/90xGxRoHrAaROrcHK1aPKaijCtSrhg==
 
-"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1:
+"strip-ansi-cjs@npm:strip-ansi@^6.0.1":
+  version "6.0.1"
+  resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
+  integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
+  dependencies:
+    ansi-regex "^5.0.1"
+
+strip-ansi@^6.0.0, strip-ansi@^6.0.1:
   version "6.0.1"
   resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
   integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
@@ -9265,7 +9281,16 @@ wordwrap@^1.0.0:
   resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb"
   integrity sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==
 
-"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0:
+"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0":
+  version "7.0.0"
+  resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
+  integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
+  dependencies:
+    ansi-styles "^4.0.0"
+    string-width "^4.1.0"
+    strip-ansi "^6.0.0"
+
+wrap-ansi@^7.0.0:
   version "7.0.0"
   resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
   integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
-- 
GitLab