Skip to content

Commit bd7489e

Browse files
authored
Allow passing in a token (#71)
* Allow passing in a token Changes to allow the token info to be retrieved and set on the API client. This is useful when running across multiple servers or when running in a serverless environment. Closes #70 * Fix ESLint errors * Fix spacing * Update examples in README
1 parent b119d1e commit bd7489e

21 files changed

+153
-31
lines changed

README.md

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,7 @@
22

33
[![npm version](https://badge.fury.io/js/gettyimages-api.svg)](https://badge.fury.io/js/gettyimages-api)
44
[![Downloads](https://img.shields.io/npm/dt/gettyimages-api.svg)](http://npm-stat.com/charts.html?package=gettyimages-api)
5-
[![](https://travis-ci.org/gettyimages/gettyimages-api_nodejs.svg?branch=master)](https://travis-ci.org/gettyimages/gettyimages-api_nodejs)
65
[![Coverage Status](https://coveralls.io/repos/github/gettyimages/gettyimages-api_nodejs/badge.svg)](https://coveralls.io/github/gettyimages/gettyimages-api_nodejs)
7-
[![Code Climate](https://codeclimate.com/github/gettyimages/gettyimages-api_nodejs/badges/gpa.svg)](https://codeclimate.com/github/gettyimages/gettyimages-api_nodejs)
86
[![Open Hub](https://img.shields.io/badge/Open-Hub-0185CA.svg)](https://www.openhub.net/p/gettyimages-api_nodejs)
97

108
## Introduction
@@ -36,6 +34,7 @@ See the [NodeJS Release Page](https://github.com/nodejs/release) for info on thi
3634
If you don't already have an API key, fill out and submit the [contact form](http://engage.gettyimages.com/api-contact) to be connected to our Sales team.
3735

3836
### Installing the package
37+
3938
The SDK is available as an [npm package](https://www.npmjs.com/package/gettyimages-api). Install in your workspace with:
4039

4140
```sh
@@ -215,6 +214,7 @@ try {
215214
console.error("An error occurred while making the custom request:", err);
216215
}
217216
```
217+
218218
### Add custom parameter and header to a search request
219219

220220
```javascript
@@ -235,3 +235,29 @@ try {
235235
console.error("An error occurred while searching for images:", err);
236236
}
237237
```
238+
239+
### Reuse a token between instantiations of the client
240+
241+
If you need to create new instances of the client between calls, such as in a
242+
serverless environment, and want to cache the access token between uses, the SDK
243+
supports this.
244+
245+
```javascript
246+
import api from "gettyimages-api";
247+
// Get the token from your cache. The following line is just an example.
248+
let token = await getTokenFromCache();
249+
250+
const creds = { apiKey: "your_api_key", apiSecret: "your_api_secret", token: token };
251+
const client = new api(creds);
252+
const response = await client.searchimagescreative()
253+
.withPage(1)
254+
.withPageSize(1)
255+
.withPhrase('beach')
256+
.execute();
257+
// get the token from the client, as it could have been updated if it was expired.
258+
token = client.token;
259+
260+
// Store the token in a cache, e.g. Redis or memcached.
261+
// The following is just an example.
262+
await setTokenInCache(token);
263+
```

gettyimages-api.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,15 @@ class GettyImagesApi {
4242
set hostName(value) {
4343
_hostName.set(this,value);
4444
}
45+
46+
get token() {
47+
return {
48+
access_token: this.creds.token.access_token,
49+
token_type: "Bearer",
50+
expiration: this.creds.token.expiration
51+
};
52+
}
53+
4554
constructor(credentials, hostName, authHostName) {
4655
if (!credentials.apiKey) {
4756
throw new SdkException("must specify an apiKey");
@@ -58,6 +67,9 @@ class GettyImagesApi {
5867
this.hostName = hostName;
5968
this.credentials = credentials;
6069
this.creds = new Credentials(credentials.apiKey, credentials.apiSecret, credentials.username, credentials.password, credentials.refresh_token, authHostName);
70+
if (credentials.token) {
71+
this.creds.token = credentials.token;
72+
}
6173
}
6274

6375
getAccessToken() {

lib/credentials.js

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,10 @@ class Credentials {
2828
_apiKey.set(this,value);
2929
}
3030

31-
get accessToken() {
31+
get token() {
3232
return _accessToken.get(this);
3333
}
34-
set accessToken(value) {
34+
set token(value) {
3535
_accessToken.set(this,value);
3636
}
3737

@@ -76,12 +76,12 @@ class Credentials {
7676
var apiSecret = this.apiSecret;
7777
var username = this.username;
7878
var password = this.password;
79-
var accessToken = this.accessToken;
79+
var token = this.token;
8080
var hostName = this.hostName;
8181

8282

8383
if (!this.shouldRefreshToken()) {
84-
return accessToken;
84+
return token;
8585
}
8686

8787
var params = {
@@ -107,9 +107,9 @@ class Credentials {
107107
var expireTime = new Date();
108108
expireTime.setSeconds(expireTime.getSeconds() + Number(response.expires_in));
109109
response.expiration = expireTime;
110-
self.accessToken = response;
110+
self.token = response;
111111

112-
return self.accessToken;
112+
return self.token;
113113
} catch (err) {
114114
return null;
115115
}
@@ -139,9 +139,9 @@ class Credentials {
139139
var expireTime = new Date();
140140
expireTime.setSeconds(expireTime.getSeconds() + Number(response.expires_in));
141141
response.expiration = expireTime;
142-
self.accessToken = response;
142+
self.token = response;
143143

144-
return self.accessToken;
144+
return self.token;
145145
} catch (err) {
146146
return null;
147147
}
@@ -150,10 +150,10 @@ class Credentials {
150150

151151

152152
shouldRefreshToken() {
153-
var accessToken = this.accessToken;
153+
var token = this.token;
154154

155-
if (accessToken && accessToken.expiration) {
156-
return new Date(Date.now() - 5000) > accessToken.expiration;
155+
if (token && token.expiration) {
156+
return new Date(Date.now() - 5000) > token.expiration;
157157
} else {
158158
return true;
159159
}

tests/auth-cache-tests.js

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
const api = require("../gettyimages-api");
2+
const nock = require("nock");
3+
const test = require("ava");
4+
var authCount = 0;
5+
6+
test.beforeEach(() => {
7+
nock("https://authentication.gettyimages.com")
8+
.post("/oauth2/token", (body) => {
9+
authCount++;
10+
return (
11+
body.client_id === "apikey" &&
12+
body.client_secret === "apisecret" &&
13+
body.grant_type === "client_credentials"
14+
);
15+
})
16+
.times(1)
17+
.reply(200, {
18+
access_token: "client_credentials_access_token",
19+
token_type: "Bearer",
20+
expires_in: 1800,
21+
});
22+
nock("https://api.gettyimages.com")
23+
.get("/v3/search/images/creative")
24+
.query({ phrase: "cat" })
25+
.times(2)
26+
.reply(200, { response: "phrase" });
27+
});
28+
29+
test("Authentication call should only be made once because client should use a cached token on the second call.", async (t) => {
30+
var client = new api({ apiKey: "apikey", apiSecret: "apisecret" });
31+
await client.searchimagescreative().withPhrase("cat").execute();
32+
console.log(JSON.stringify(client.token, null, 2));
33+
await client.searchimagescreative().withPhrase("cat").execute();
34+
t.is(
35+
authCount,
36+
1,
37+
"Authentication call should only be made once because client should use a cached token on the second call."
38+
);
39+
});

tests/auth-set-token.js

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
const api = require("../gettyimages-api");
2+
const nock = require("nock");
3+
const test = require("ava");
4+
var authCount = 0;
5+
6+
test.beforeEach(() => {
7+
nock("https://authentication.gettyimages.com")
8+
.post("/oauth2/token", (body) => {
9+
authCount++;
10+
return (
11+
body.client_id === "apikey" &&
12+
body.client_secret === "apisecret" &&
13+
body.grant_type === "client_credentials"
14+
);
15+
})
16+
.times(0)
17+
.reply(200, {
18+
access_token: "client_credentials_access_token",
19+
token_type: "Bearer",
20+
expires_in: 1800,
21+
});
22+
nock("https://api.gettyimages.com")
23+
.get("/v3/search/images/creative")
24+
.query({ phrase: "cat" })
25+
.times(2)
26+
.reply(200, { response: "phrase" });
27+
});
28+
29+
test("Authentication call should not be made because the token was provided by the caller.", async (t) => {
30+
var client = new api({
31+
apiKey: "apikey",
32+
apiSecret: "apisecret",
33+
token: {
34+
access_token: "provided_access_token",
35+
token_type: "Bearer",
36+
expiration: Date.now() + 1800000,
37+
},
38+
});
39+
await client.searchimagescreative().withPhrase("cat").execute();
40+
t.is(
41+
authCount,
42+
0,
43+
"Authentication call should not be made because the token was provided by the caller."
44+
);
45+
});

tests/authtests.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,20 +8,20 @@ test.beforeEach(() => {
88
.reply(200, {
99
access_token: "client_credentials_access_token",
1010
token_type: "Bearer",
11-
expires_in: "1800"
11+
expires_in: 1800
1212
})
1313
.post("/oauth2/token", "client_id=apikey&client_secret=apisecret&grant_type=password&username=username&password=password")
1414
.reply(200, {
1515
access_token: "resource_owner_access_token",
1616
token_type: "Bearer",
17-
expires_in: "1800",
17+
expires_in: 1800,
1818
refresh_token: "refreshtoken"
1919
})
2020
.post("/oauth2/token", "client_id=apikey&client_secret=apisecret&refresh_token=refreshtoken&grant_type=refresh_token")
2121
.reply(200, {
2222
access_token: "accesstoken",
2323
token_type: "Bearer",
24-
expires_in: "1800"
24+
expires_in: 1800
2525
});
2626
});
2727

tests/collectionstests.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ test.before(() => {
88
.reply(200, {
99
access_token: "client_credentials_access_token",
1010
token_type: "Bearer",
11-
expires_in: "1800"
11+
expires_in: 1800
1212
});
1313
nock("https://api.gettyimages.com")
1414
.get("/v3/collections")

tests/countriestests.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ test.before(() => {
88
.reply(200, {
99
access_token: "client_credentials_access_token",
1010
token_type: "Bearer",
11-
expires_in: "1800"
11+
expires_in: 1800
1212
});
1313
nock("https://api.gettyimages.com")
1414
.get("/v3/countries")

tests/customparamsandheaderstests.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ test.beforeEach(() => {
88
.reply(200, {
99
access_token: "client_credentials_access_token",
1010
token_type: "Bearer",
11-
expires_in: "1800"
11+
expires_in: 1800
1212
});
1313
nock("https://api.gettyimages.com")
1414
.get("/v3/search/images/creative")

tests/customrequesttests.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ test.beforeEach(() => {
88
.reply(200, {
99
access_token: "client_credentials_access_token",
1010
token_type: "Bearer",
11-
expires_in: "1800"
11+
expires_in: 1800
1212
});
1313
nock("https://api.gettyimages.com")
1414
.get("/v3/search/images")

0 commit comments

Comments
 (0)