Plugin boldSmartLock

Voici les informations sur mon nouveau plugin :

  • Bold Smartlock et boldSmartLock
  • Il permet de contrôler sa serrure Bold smartlock
  • Langages utilisés : PHP
  • Utilise-t-il un démon ? oui pour la mise a jours des serrure
  • Utilise-t-il des dépendances particulières ? Non
  • Utilise-t-il des crons ? Non
  • Possède-t-il un panel dédié ? Non
  • Payant || gratuit ? Gratuit

@Loic, je suis relancé pour l’intégration de bold sur Jeedom.
A tu pue regarder avec Bold ce qui coince?

Bonjour,
Oui j’ai chercher mais je trouve pas… Je seche completement on utilise le meme systeme pour des dizaines de service sans aucun soucis (meme enedis qui a une implementation assez castrophique) et ca marche, les seuls chez qui ca marche pas c’est Bold

Bonjour

Merci du retour.
On est donc sur la même problématique.
Côté bold il ne voit pas la requête.
Est ce que côté jeedom tu as des log ou un historique des requêtes

Ben rien de plus que ce que je t’avais déjà donné

Je vais rechercher dans mes mails mais il me semble que la requête ne fonctionnait pas

Edit

J’ai retrouvé le retour de bold.
Sur leur serveur aucune requête arrive.

Il on fait une requête par curl au lieu de xrf et la ça fonctionne

« However if I execute the exact same query for the last 7 days, I see no results which seems to indicate no calls are happening from within Jeedom. Maybe this has something to do with the XSRF-TOKEN? May I suggest you try with « curl » first to see if that works? »

Je ne connais pas le xrf est ce que tu vois quel différence y a entre les 2 méthode ?

Je serais pas te dire le token c’est je pense un header mais si je sais pas quoi mettre dedans ça me sert pas beaucoup

@loic

Est ce que les autres services qui ont un code d’authentification dans se format

code=87e1e59f-d542-4d60-8eb9-xxxxxxx

Les - ne sont normalement pas un problème mais c’est la seule chose qui vient de bold et qui pourrait bloquer l’exécution de la commande.

J’ai regarder les requêtes qui arrive chez moi après l’authentification bold


Est ce qu’il n’y a pas un soucis sur l’association de mon jeedom au retour et il n’arrive pas a matché

Le code est bien le même format que pour tous les autres services donc pas de soucis là dessus. La l’erreur c’est c’que côté bold il me renvoi pas le token donc forcément je peux pas aller plus loin.

Del leur côté il ne voit pas la requête.
C’est qu’il doit y avoir un contrôle de requête qui n’est pas validé

A ton avis comment avancer sur le sujet avec Bold

Je sais pas du tout c’est vraiment de leur coté le soucis (ou plutot un truc qu’il faut qu’on fasse et qu’on ne fait pas). Voila ce que leur site me repond :

[oauth/oauth/redirect][bold] Error on grant authorization code :  AxiosError: Request failed with status code 403
    at settle (/usr/cloud-service/node_modules/axios/dist/node/axios.cjs:2026:12)
    at IncomingMessage.handleStreamEnd (/usr/cloud-service/node_modules/axios/dist/node/axios.cjs:3142:11)
    at IncomingMessage.emit (node:events:530:35)
    at endReadableNT (node:internal/streams/readable:1698:12)
    at process.processTicksAndRejections (node:internal/process/task_queues:82:21)
    at Axios.request (/usr/cloud-service/node_modules/axios/dist/node/axios.cjs:4252:41)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5) {
  code: 'ERR_BAD_REQUEST',
  config: {
    transitional: {
      silentJSONParsing: true,
      forcedJSONParsing: true,
      clarifyTimeoutError: false
    },
    adapter: [ 'xhr', 'http', 'fetch' ],
    transformRequest: [ [Function: transformRequest] ],
    transformResponse: [ [Function: transformResponse] ],
    timeout: 0,
    xsrfCookieName: 'XSRF-TOKEN',
    xsrfHeaderName: 'X-XSRF-TOKEN',
    maxContentLength: -1,
    maxBodyLength: -1,
    env: { FormData: [Function], Blob: [class Blob] },
    validateStatus: [Function: validateStatus],
    headers: Object [AxiosHeaders] {
      Accept: 'application/json, text/plain, */*',
      'Content-Type': 'application/x-www-form-urlencoded',
      'User-Agent': 'axios/1.7.8',
      'Content-Length': '190',
      'Accept-Encoding': 'gzip, compress, deflate, br'
    },
    method: 'post',
    url: 'https://api.boldsmartlock.com/v2/oauth/token',
    data: 'grant_type=authorization_code&client_id=XXXXX&client_secret=XXXXXXX&code=70a72a62-c915-4ee2-9065-db78faed2ff6&redirect_uri=https%3A%2F%2Fcloud.jeedom.com%2Foauth%2Fredirect'
  },
  request: <ref *1> ClientRequest {
    _events: [Object: null prototype] {
      abort: [Function (anonymous)],
      aborted: [Function (anonymous)],
      connect: [Function (anonymous)],
      error: [Function (anonymous)],
      socket: [Function (anonymous)],
      timeout: [Function (anonymous)],
      finish: [Function: requestOnFinish]
    },
    _eventsCount: 7,
    _maxListeners: undefined,
    outputData: [],
    outputSize: 0,
    writable: true,
    destroyed: true,
    _last: false,
    chunkedEncoding: false,
--
    useChunkedEncodingByDefault: true,
    sendDate: false,
    _removedConnection: false,
    _removedContLen: false,
    _removedTE: false,
    strictContentLength: false,
    _contentLength: '190',
    _hasBody: true,
    _trailer: '',
    finished: true,
    _headerSent: true,
    _closed: true,
    socket: TLSSocket {
      _tlsOptions: [Object],
      _secureEstablished: true,
      _securePending: false,
      _newSessionPending: false,
      _controlReleased: true,
      secureConnecting: false,
      _SNICallback: null,
      servername: 'api.boldsmartlock.com',
      alpnProtocol: false,
      authorized: true,
      authorizationError: null,
      encrypted: true,
      _events: [Object: null prototype],
      _eventsCount: 9,
      connecting: false,
      _hadError: false,
      _parent: null,
      _host: 'api.boldsmartlock.com',
      _closeAfterHandlingError: false,
      _readableState: [ReadableState],
      _writableState: [WritableState],
      allowHalfOpen: false,
      _maxListeners: undefined,
      _sockname: null,
      _pendingData: null,
      _pendingEncoding: '',
      server: undefined,
      _server: null,
      ssl: [TLSWrap],
      _requestCert: true,
      _rejectUnauthorized: true,
      timeout: 5000,
      parser: null,
      _httpMessage: null,
      autoSelectFamilyAttemptedAddresses: [Array],
      [Symbol(alpncallback)]: null,
      [Symbol(res)]: [TLSWrap],
      [Symbol(verified)]: true,
--
        [Symbol(triggerId)]: 116604932
      },
      [Symbol(kBuffer)]: null,
      [Symbol(kBufferCb)]: null,
      [Symbol(kBufferGen)]: null,
      [Symbol(shapeMode)]: true,
      [Symbol(kCapture)]: false,
      [Symbol(kSetNoDelay)]: false,
      [Symbol(kSetKeepAlive)]: true,
      [Symbol(kSetKeepAliveInitialDelay)]: 1,
      [Symbol(kBytesRead)]: 0,
      [Symbol(kBytesWritten)]: 0,
      [Symbol(connect-options)]: [Object]
    },
    _header: 'POST /v2/oauth/token HTTP/1.1\r\n' +
      'Accept: application/json, text/plain, */*\r\n' +
      'Content-Type: application/x-www-form-urlencoded\r\n' +
      'User-Agent: axios/1.7.8\r\n' +
      'Content-Length: 190\r\n' +
      'Accept-Encoding: gzip, compress, deflate, br\r\n' +
      'Host: api.boldsmartlock.com\r\n' +
      'Connection: keep-alive\r\n' +
      '\r\n',
    _keepAliveTimeout: 0,
    _onPendingData: [Function: nop],
    agent: Agent {
      _events: [Object: null prototype],
      _eventsCount: 2,
      _maxListeners: undefined,
      defaultPort: 443,
      protocol: 'https:',
      options: [Object: null prototype],
      requests: [Object: null prototype] {},
      sockets: [Object: null prototype],
      freeSockets: [Object: null prototype],
      keepAliveMsecs: 1000,
      keepAlive: true,
      maxSockets: Infinity,
      maxFreeSockets: 256,
      scheduling: 'lifo',
      maxTotalSockets: Infinity,
--
      _maxListeners: undefined,
      socket: null,
      httpVersionMajor: 1,
      httpVersionMinor: 1,
      httpVersion: '1.1',
      complete: true,
      rawHeaders: [Array],
      rawTrailers: [],
      joinDuplicateHeaders: undefined,
      aborted: false,
      upgrade: false,
      url: '',
      method: null,
      statusCode: 403,
      statusMessage: 'Forbidden',
      client: [TLSSocket],
      _consuming: false,
      _dumped: false,
      req: [Circular *1],
      _eventsCount: 4,
      responseUrl: 'https://api.boldsmartlock.com/v2/oauth/token',
      redirects: [],
      [Symbol(shapeMode)]: true,
      [Symbol(kCapture)]: false,
      [Symbol(kHeaders)]: [Object],
      [Symbol(kHeadersCount)]: 10,
      [Symbol(kTrailers)]: null,
      [Symbol(kTrailersCount)]: 0
    },
    aborted: false,
    timeoutCb: null,
    upgradeOrConnect: false,
    parser: null,
    maxHeadersCount: null,
    reusedSocket: false,
    host: 'api.boldsmartlock.com',
    protocol: 'https:',
    _redirectable: Writable {
      _events: [Object],
      _writableState: [WritableState],
      _maxListeners: undefined,
      _options: [Object],
      _ended: true,
      _ending: true,
      _redirectCount: 0,
      _redirects: [],
      _requestBodyLength: 190,
      _requestBodyBuffers: [],
      _eventsCount: 3,
      _onNativeResponse: [Function (anonymous)],
      _currentRequest: [Circular *1],
      _currentUrl: 'https://api.boldsmartlock.com/v2/oauth/token',
      [Symbol(shapeMode)]: true,
      [Symbol(kCapture)]: false
    },
    [Symbol(shapeMode)]: false,
    [Symbol(kCapture)]: false,
    [Symbol(kBytesWritten)]: 0,
    [Symbol(kNeedDrain)]: false,
    [Symbol(corked)]: 0,
    [Symbol(kOutHeaders)]: [Object: null prototype] {
      accept: [Array],
      'content-type': [Array],
      'user-agent': [Array],
      'content-length': [Array],
      'accept-encoding': [Array],
      host: [Array]
    },
    [Symbol(errored)]: null,
    [Symbol(kHighWaterMark)]: 16384,
    [Symbol(kRejectNonStandardBodyWrites)]: false,
    [Symbol(kUniqueHeaders)]: null
--
      server: 'awselb/2.0',
      date: 'Fri, 24 Jan 2025 04:51:41 GMT',
      'content-type': 'text/html',
      'content-length': '118',
      connection: 'keep-alive'
    },
    config: {
      transitional: [Object],
      adapter: [Array],
      transformRequest: [Array],
      transformResponse: [Array],
      timeout: 0,
      xsrfCookieName: 'XSRF-TOKEN',
      xsrfHeaderName: 'X-XSRF-TOKEN',
      maxContentLength: -1,
      maxBodyLength: -1,
      env: [Object],
      validateStatus: [Function: validateStatus],
      headers: [Object [AxiosHeaders]],
      method: 'post',
      url: 'https://api.boldsmartlock.com/v2/oauth/token',
      data: 'grant_type=authorization_code&client_id=XXXXXXX&client_secret=XXXXXXX&code=70a72a62-c915-4ee2-9065-db78faed2ff6&redirect_uri=https%3A%2F%2Fcloud.jeedom.com%2Foauth%2Fredirect'
    },
    request: <ref *1> ClientRequest {
      _events: [Object: null prototype],
      _eventsCount: 7,
      _maxListeners: undefined,
      outputData: [],
      outputSize: 0,
      writable: true,
      destroyed: true,
      _last: false,
      chunkedEncoding: false,
      shouldKeepAlive: true,
      maxRequestsOnConnectionReached: false,
      _defaultKeepAlive: true,
      useChunkedEncodingByDefault: true,
      sendDate: false,
      _removedConnection: false,
      _removedContLen: false,
      _removedTE: false,
      strictContentLength: false,
      _contentLength: '190',
      _hasBody: true,
      _trailer: '',
      finished: true,
      _headerSent: true,
      _closed: true,
      socket: [TLSSocket],
      _header: 'POST /v2/oauth/token HTTP/1.1\r\n' +
        'Accept: application/json, text/plain, */*\r\n' +
        'Content-Type: application/x-www-form-urlencoded\r\n' +
        'User-Agent: axios/1.7.8\r\n' +
        'Content-Length: 190\r\n' +
        'Accept-Encoding: gzip, compress, deflate, br\r\n' +
        'Host: api.boldsmartlock.com\r\n' +
        'Connection: keep-alive\r\n' +
        '\r\n',
      _keepAliveTimeout: 0,
      _onPendingData: [Function: nop],
      agent: [Agent],
      socketPath: undefined,
      method: 'POST',
      maxHeaderSize: undefined,
      insecureHTTPParser: undefined,
      joinDuplicateHeaders: undefined,
      path: '/v2/oauth/token',
      _ended: true,
      res: [IncomingMessage],
      aborted: false,
      timeoutCb: null,
      upgradeOrConnect: false,
      parser: null,
      maxHeadersCount: null,
      reusedSocket: false,
      host: 'api.boldsmartlock.com',
      protocol: 'https:',
      _redirectable: [Writable],
      [Symbol(shapeMode)]: false,
      [Symbol(kCapture)]: false,
      [Symbol(kBytesWritten)]: 0,
      [Symbol(kNeedDrain)]: false,
      [Symbol(corked)]: 0,
      [Symbol(kOutHeaders)]: [Object: null prototype],
      [Symbol(errored)]: null,
      [Symbol(kHighWaterMark)]: 16384,
      [Symbol(kRejectNonStandardBodyWrites)]: false,
      [Symbol(kUniqueHeaders)]: null
    },
    data: '<html>\r\n' +
      '<head><title>403 Forbidden</title></head>\r\n' +
      '<body>\r\n' +
      '<center><h1>403 Forbidden</h1></center>\r\n' +
      '</body>\r\n' +
      '</html>\r\n'
  },

Essayez peut-etre de faire les requetes avec des outils comme postman ou use bruno, ca sera plus facile de comprendre ce qu’il se passe.

Ça viendrait pas d’ici ?

La requête par un simple curl fonctionne lorsque je l’ai fait en standalown.
Ce mode ne peut pas être conservé et les services Jeedom integre déjà pour d’autres plugin cette méthode.

Bold a essayé cette requête qui est vue par leur serveur

curl -XPOST -H 'Content-Type: application/x-www-form-urlencoded' -d "grant_type=authorization_code&code=87e1e59f-d542-4d60-8eb9-a95ad9b541e5&client_id=xxx&client_secret=xxxxxxxxxx&redirect_uri=https%3A%2F%2Fcloud.jeedom.com%2Foauth%2Fredirect" https://api.boldsmartlock.com/v2/oauth/token

tu as essayé
curl -XPOST -H 'Content-Type: application/x-www-form-urlencoded' -H 'User-Agent: axios/1.7.8' ...

1 « J'aime »

J’arrive a recuperer le code depuis l’erreur ce qui me permet de prendre la main sur mon jeedom
Je récupère bien un token avec ce header
0000|[2025-01-24 18:47:21] DEBUG : Request: https://api.boldsmartlock.com/v2/oauth/token
[« Content-Type: application/x-www-form-urlencoded »,« User-Agent: axios/1.7.8 »]

Je pense que l’idée était de bien remettre tout les headers envoyés afin de reproduire l’erreur avec curl. Ca permettra de les retirer un a un et de voir ce qui bloque.

Oui ce n’est pas faut.

J’ai du etre trop brutal je ne peux plus me connecter a mon compte

Je regaderais ca plus tard

Voici la commande complète :

curl -X POST 'https://api.boldsmartlock.com/v2/oauth/token' \
-H 'Accept: application/json, text/plain, */*' \
-H 'Content-Type: application/x-www-form-urlencoded' \
-H 'User-Agent: axios/1.7.8' \
--data-urlencode 'grant_type=authorization_code' \
--data-urlencode 'client_id=XXXXX' \
--data-urlencode 'client_secret=XXXXXXX' \
--data-urlencode 'code=70a72a62-c915-4ee2-9065-db78faed2ff6' \
--data-urlencode 'redirect_uri=https://cloud.jeedom.com/oauth/redirect'

Cette commande reprend tous les éléments de la requête qui a échoué :

  • La méthode POST
  • L’URL de l’endpoint
  • Les headers exacts
  • Les données du formulaire encodées en URL

L’erreur 403 indique que l’accès est interdit, ce qui peut être dû à :

  • Des identifiants invalides (client_id/client_secret)
  • Un code d’autorisation expiré ou invalide
  • Une URI de redirection non autorisée

Non déjà vérifié et on ne pourrait pas avoir le code pour le token sans

Possible mais je récupère le code sur la requête 403 et ça passe.

C’est bien l’adresse autorisé si je met autre chose ça passe pas. Je ne vois pas pourquoi il serait différent dans le service jeedom. Peut être l’encodage ???

La je n’arrive plus à me connecter sûrement qu’ils ont détecté que l’URL de la requête ne venait pas de l’URI autorisé et ont bloqué mon compte.
Je leur ai fait une demande.
Mais je ne peux du coup plus tester
La seule différence c’est le header