Skip to content

Commit e90404d

Browse files
committed
fix: remove deprecated Client Credentials grant type
1 parent 8f28592 commit e90404d

File tree

3 files changed

+79
-108
lines changed

3 files changed

+79
-108
lines changed

README.md

Lines changed: 76 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -25,71 +25,96 @@ npm install netatmo-nodejs-api
2525

2626
## Usage
2727

28-
### Basic example with refresh token and client credentials grant type
28+
You need to [create an application](https://dev.netatmo.com/apps/createanapp#form)
29+
30+
### ~~Basic example with Client Credentials grant type~~
31+
32+
This method has been deprecated, see [Natatmo documentation](https://dev.netatmo.com/apidocumentation/oauth#client-credential)
33+
34+
### Basic example with Refresh Token grant type
35+
36+
You need to generate a token on [Netatmo website](https://dev.netatmo.com/apps/):
37+
- choose scopes
38+
- click `generate token` button and accept the condition
39+
- copy both `Access Token` and `Refresh Token` and use it in the following code
40+
2941
```js
3042
const { NetatmoClient, SCOPE_BASIC_CAMERA } = require('netatmo-nodejs-api')
3143

32-
// you need to set your own information
33-
const clientId = '60...'
34-
const clientSecret = 'abc...'
35-
const username = 'user@domain'
36-
const password = 'pass'
37-
let refreshToken = ''
38-
let accessToken = ''
39-
let expiresInTimestamp = 0
40-
41-
try {
42-
// create client
43-
const client = new NetatmoClient(clientId, clientSecret, SCOPE_BASIC_CAMERA, { timeout: 1000 })
44-
45-
// authenticate
46-
if (!client.checkAndSetAccesToken(accessToken, expiresInTimestamp)) {
47-
if (refreshToken) {
48-
// use previous refresh token
49-
({ accessToken, refreshToken, expiresInTimestamp } = await client.authenticateByRefreshToken(refreshToken))
50-
} else {
51-
// use user credentials
52-
({ accessToken, refreshToken, expiresInTimestamp } = await client.authenticateByClientCredentials(username, password))
44+
async function main () {
45+
// you need to set your own information
46+
const clientId = ''
47+
const clientSecret = ''
48+
let accessToken = ''
49+
let refreshToken = ''
50+
let expiresInTimestamp = 0
51+
52+
try {
53+
// create client
54+
const client = new NetatmoClient(clientId, clientSecret, SCOPE_BASIC_CAMERA, { timeout: 1000 })
55+
56+
// authenticate
57+
if (!client.checkAndSetAccesToken(accessToken, expiresInTimestamp)) {
58+
if (refreshToken) {
59+
// use previous refresh token
60+
({ accessToken, refreshToken, expiresInTimestamp } = await client.authenticateByRefreshToken(refreshToken))
61+
// you should store accessToken, refreshToken, expiresInTimestamp for further request
62+
console.log('update the code with following 3 lines:')
63+
console.log(` let accessToken = '${accessToken}'`)
64+
console.log(` let refreshToken = '${refreshToken}'`)
65+
console.log(` let expiresInTimestamp = ${expiresInTimestamp}`)
66+
} else {
67+
throw new Error('Refresh token is missing')
68+
}
5369
}
54-
// you should store accessToken, refreshToken, expiresInTimestamp for further request
55-
}
5670

57-
// get data
58-
const homes = await client.getHomes()
59-
} catch (error) {
60-
console.log(error)
71+
// get data
72+
const homes = await client.getHomes()
73+
console.log(homes)
74+
} catch (error) {
75+
console.log(error)
76+
}
6177
}
78+
79+
main()
6280
```
6381

64-
### Authenticate wrapper (try access token, refresh token or client credentials)
82+
### Authenticate wrapper (try access token or refresh token)
6583

66-
You can use the `authenticate` method which wrap 3 authentication methods.
84+
You can use the `authenticate` method which wrap 2 authentication methods.
6785

6886
```js
6987
const { NetatmoClient, SCOPE_BASIC_CAMERA } = require('netatmo-nodejs-api')
7088

71-
// you need to set your own information
72-
const clientId = '60...'
73-
const clientSecret = 'abc...'
74-
const username = 'user@domain'
75-
const password = 'pass'
76-
let refreshToken = ''
77-
let accessToken = ''
78-
let expiresInTimestamp = 0
79-
80-
try {
81-
// create client
82-
const client = new NetatmoClient(clientId, clientSecret, SCOPE_BASIC_CAMERA, { timeout: 1000 })
83-
84-
// authenticate
85-
({ accessToken, refreshToken, expiresInTimestamp } = await client.authenticate(accessToken, refreshToken, expiresInTimestamp, username, password))
86-
// you should store accessToken, refreshToken, expiresInTimestamp for further request
87-
88-
// get data
89-
const homes = await client.getHomes()
90-
} catch (error) {
91-
console.log(error)
89+
async function main () {
90+
// you need to set your own information
91+
const clientId = ''
92+
const clientSecret = ''
93+
let refreshToken = ''
94+
let accessToken = ''
95+
let expiresInTimestamp = 0
96+
97+
try {
98+
// create client
99+
const client = new NetatmoClient(clientId, clientSecret, SCOPE_BASIC_CAMERA, { timeout: 1000 });
100+
101+
// authenticate
102+
({ accessToken, refreshToken, expiresInTimestamp } = await client.authenticate(accessToken, refreshToken, expiresInTimestamp))
103+
// you should store accessToken, refreshToken, expiresInTimestamp for further request
104+
console.log('update the code with following:', refreshToken)
105+
console.log(` let accessToken = '${accessToken}'`)
106+
console.log(` let refreshToken = '${refreshToken}'`)
107+
console.log(` let expiresInTimestamp = ${expiresInTimestamp}`)
108+
109+
// get data
110+
const homes = await client.getHomes()
111+
console.log(homes)
112+
} catch (error) {
113+
console.log(error)
114+
}
92115
}
116+
117+
main()
93118
```
94119

95120
## Versioning

lib/index.js

Lines changed: 3 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -60,9 +60,6 @@ class NetatmoClient {
6060
this.clientSecret = clientSecret
6161
this.scope = scope
6262
this.requestConfig = requestConfig
63-
// client credentials
64-
this.username = null
65-
this.password = null
6663
// authorization code
6764
this.authorizationCode = null
6865
this.redirectUrl = null
@@ -79,11 +76,9 @@ class NetatmoClient {
7976
* @param {string} accessToken Access token for your user
8077
* @param {string} refreshToken Refresh token to get a new access token
8178
* @param {number} expiresInTimestamp Validity timelaps as timestamp
82-
* @param {string} username User address email
83-
* @param {string} password User password
8479
* @return {Token} Token `{accessToken, refreshToken, expiresInTimestamp}`
8580
*/
86-
async authenticate (accessToken = null, refreshToken = null, expiresInTimestamp = 0, username = null, password = null) {
81+
async authenticate (accessToken = null, refreshToken = null, expiresInTimestamp = 0) {
8782
if (this.checkAndSetAccesToken(accessToken, expiresInTimestamp)) {
8883
if (refreshToken) {
8984
this.refreshToken = refreshToken
@@ -93,7 +88,7 @@ class NetatmoClient {
9388
if (refreshToken) {
9489
return this.authenticateByRefreshToken(refreshToken)
9590
}
96-
return this.authenticateByClientCredentials(username, password)
91+
throw new Error('Refresh token is missing')
9792
}
9893

9994
/**
@@ -148,30 +143,6 @@ class NetatmoClient {
148143
return this.setToken(authentication)
149144
}
150145

151-
/**
152-
* Authenticate with client credentials
153-
*
154-
* @param {string} username User address email
155-
* @param {string} password User password
156-
* @return {Token} Token `{accessToken, refreshToken, expiresInTimestamp}`
157-
*/
158-
async authenticateByClientCredentials (username, password) {
159-
if (!username || !password) {
160-
throw new Error('Username and password must be provided')
161-
}
162-
this.username = username
163-
this.password = password
164-
const authentication = await this.request(HTTP_POST, PATH_AUTH, null, {
165-
grant_type: 'password',
166-
client_id: this.clientId,
167-
client_secret: this.clientSecret,
168-
username: this.username,
169-
password: this.password,
170-
scope: this.scope,
171-
})
172-
return this.setToken(authentication)
173-
}
174-
175146
/**
176147
* Authenticate with an existing refresh token
177148
*
@@ -266,7 +237,7 @@ class NetatmoClient {
266237
if (!isRetry && (error.response.status === 403 || error.response.status === 401) && error.response.data.error && error.response.data.error.code && error.response.data.error.code === 3) {
267238
// expired access token error, remove it and try to get a new one before a retry
268239
this.accessToken = null
269-
await this.authenticate(null, this.refreshToken, this.expiresInTimestamp, this.username, this.password)
240+
await this.authenticate(null, this.refreshToken, this.expiresInTimestamp)
270241
return await this.request(method, path, params, data, true)
271242
}
272243
if (error.response.data.error_description) {

test/index.test.js

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,6 @@ const clientSecret = 'clientSecret'
1111
const scope = 'scope'
1212
const requestConfig = { dummy: '1' }
1313
const redirectUrl = 'http://localhost/auth'
14-
const username = 'user'
15-
const password = 'password'
1614
const authResult = {
1715
access_token: '2YotnFZFEjr1zCsicMWpAA',
1816
expires_in: 10800,
@@ -141,22 +139,6 @@ describe('Authentication', function () {
141139
})
142140
})
143141

144-
describe('User credentials grant type', function () {
145-
it('should throw error if user credentials are missing', async function () {
146-
const client = new NetatmoClient(clientId, clientSecret, scope, {})
147-
await assert.rejects(async () => { await client.authenticateByClientCredentials(null, password) }, new Error('Username and password must be provided'))
148-
await assert.rejects(async () => { await client.authenticateByClientCredentials(username, undefined) }, new Error('Username and password must be provided'))
149-
})
150-
151-
it('should obtain token with client credentials', async function () {
152-
const client = new NetatmoClient(clientId, clientSecret, scope, {})
153-
const { accessToken, refreshToken, expiresInTimestamp } = await client.authenticateByClientCredentials(username, password)
154-
assert.strictEqual(accessToken, authResult.access_token)
155-
assert.strictEqual(refreshToken, authResult.refresh_token)
156-
assert.strictEqual(expiresInTimestamp > Date.now() / 1000, true)
157-
})
158-
})
159-
160142
describe('Refresh token', function () {
161143
it('should throw error if refresh token is missing', async function () {
162144
const client = new NetatmoClient(clientId, clientSecret, scope, {})
@@ -185,13 +167,6 @@ describe('Authentication', function () {
185167
assert.strictEqual(refreshToken, authResult.refresh_token)
186168
assert.strictEqual(expiresInTimestamp > Date.now() / 1000, true)
187169
})
188-
it('should obtain token with client credentials', async function () {
189-
const client = new NetatmoClient(clientId, clientSecret, scope, {})
190-
const { accessToken, refreshToken, expiresInTimestamp } = await client.authenticate(undefined, undefined, 0, username, password)
191-
assert.strictEqual(accessToken, authResult.access_token)
192-
assert.strictEqual(refreshToken, authResult.refresh_token)
193-
assert.strictEqual(expiresInTimestamp > Date.now() / 1000, true)
194-
})
195170
})
196171

197172
describe('Invalid token', function () {

0 commit comments

Comments
 (0)