Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: smartcar/node-sdk
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v4.0.4
Choose a base ref
...
head repository: smartcar/node-sdk
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: master
Choose a head ref
Loading
Showing with 55,285 additions and 1,607 deletions.
  1. +1 −0 .eslintignore
  2. +2 −0 .eslintrc.js
  3. +3 −0 .gitignore
  4. +4 −4 .nycrc.json
  5. +1 −0 .prettierignore
  6. +30 −16 .travis.yml
  7. +80 −62 README.md
  8. +1 −1 doc/.template.hbs
  9. +1,387 −0 doc/AuthClient.html
  10. +1,139 −0 doc/SmartcarError.html
  11. +358 −0 doc/SmartcarService.html
  12. +5,219 −0 doc/Vehicle.html
  13. BIN doc/fonts/OpenSans-Bold-webfont.eot
  14. +1,830 −0 doc/fonts/OpenSans-Bold-webfont.svg
  15. BIN doc/fonts/OpenSans-Bold-webfont.woff
  16. BIN doc/fonts/OpenSans-BoldItalic-webfont.eot
  17. +1,830 −0 doc/fonts/OpenSans-BoldItalic-webfont.svg
  18. BIN doc/fonts/OpenSans-BoldItalic-webfont.woff
  19. BIN doc/fonts/OpenSans-Italic-webfont.eot
  20. +1,830 −0 doc/fonts/OpenSans-Italic-webfont.svg
  21. BIN doc/fonts/OpenSans-Italic-webfont.woff
  22. BIN doc/fonts/OpenSans-Light-webfont.eot
  23. +1,831 −0 doc/fonts/OpenSans-Light-webfont.svg
  24. BIN doc/fonts/OpenSans-Light-webfont.woff
  25. BIN doc/fonts/OpenSans-LightItalic-webfont.eot
  26. +1,835 −0 doc/fonts/OpenSans-LightItalic-webfont.svg
  27. BIN doc/fonts/OpenSans-LightItalic-webfont.woff
  28. BIN doc/fonts/OpenSans-Regular-webfont.eot
  29. +1,831 −0 doc/fonts/OpenSans-Regular-webfont.svg
  30. BIN doc/fonts/OpenSans-Regular-webfont.woff
  31. +4,859 −0 doc/global.html
  32. +211 −0 doc/index.html
  33. +418 −0 doc/index.js.html
  34. +299 −0 doc/lib_auth-client.js.html
  35. +179 −0 doc/lib_smartcar-error.js.html
  36. +193 −0 doc/lib_smartcar-service.js.html
  37. +180 −0 doc/lib_util.js.html
  38. +1,155 −0 doc/lib_vehicle.js.html
  39. +3,098 −0 doc/module-smartcar.html
  40. +1,483 −290 doc/readme.md
  41. +25 −0 doc/scripts/linenumber.js
  42. +202 −0 doc/scripts/prettify/Apache-License-2.0.txt
  43. +2 −0 doc/scripts/prettify/lang-css.js
  44. +28 −0 doc/scripts/prettify/prettify.js
  45. +358 −0 doc/styles/jsdoc-default.css
  46. +111 −0 doc/styles/prettify-jsdoc.css
  47. +132 −0 doc/styles/prettify-tomorrow.css
  48. +295 −46 index.js
  49. +128 −68 lib/auth-client.js
  50. +3 −1 lib/config.json
  51. +0 −174 lib/errors.js
  52. +128 −0 lib/smartcar-error.js
  53. +142 −0 lib/smartcar-service.js
  54. +68 −43 lib/util.js
  55. +1,004 −126 lib/vehicle.js
  56. +19,258 −0 package-lock.json
  57. +21 −16 package.json
  58. +0 −7 test/.eslintrc.js
  59. +40 −0 test/end-to-end/auth-client.js
  60. +136 −0 test/end-to-end/helpers/index.js
  61. +139 −0 test/end-to-end/index.js
  62. +102 −0 test/end-to-end/util.js
  63. +663 −0 test/end-to-end/vehicle.js
  64. +0 −102 test/index.js
  65. +0 −23 test/lib/errors.js
  66. +0 −279 test/lib/util.js
  67. +0 −265 test/lib/vehicle.js
  68. +229 −0 test/unit/index.js
  69. +124 −84 test/{ → unit}/lib/auth-client.js
  70. +277 −0 test/unit/lib/util.js
  71. +383 −0 test/unit/lib/vehicle.js
1 change: 1 addition & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
coverage
doc
2 changes: 2 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
'use strict';

module.exports = {
extends: 'smartcar',
};
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -49,3 +49,6 @@ Package Control.cache/
Package Control.ca-certs/
bh_unicode_properties.cache
GitHub.sublime-settings

## env
.env
8 changes: 4 additions & 4 deletions .nycrc.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
{
"lines": 98,
"branches": 98,
"functions": 98,
"statements": 98,
"lines": 95,
"branches": 95,
"functions": 95,
"statements": 95,
"all" : false,
"cache": true,
"reporter": [
1 change: 1 addition & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
**
46 changes: 30 additions & 16 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,35 +1,49 @@
dist: xenial

services:
- xvfb

addons:
firefox: latest

language:
- node_js

node_js:
- 10
- 8
- 6
- "16"
- "14"
- "12"

before_install:
- npm install -g npm@8.3.0

cache:
directories:
- $HOME/.npm
- node_modules
- .eslintcache
- "$HOME/.npm"
- ".eslintcache"

branches:
except:
# Don't run on tag pushes
- /^v\d+\.\d+\.\d+$/
if: tag IS blank # do not build tags

notifications:
slack: smartcar:PGJmjtKFPytU5E2FwsImdVp8
slack:
secure: "CHS39tAvw6WiIN8cYSyE3QT2PVeFdrHszT/00kU3pb1BH5Ec5JYx5U7bMrVf3yq3GQC/wxBhXs4E119LwZM0n04CGUOshShqSkLeUf9RfWYlqx2Qw2+tT8sOi+OXCzE+yaG3Yt+TWFqKyC5t0A9jZX6cdJbcBaKX2wJiOyI/HiTpXHXrJgeeflxRe03KDpIfpmWgpMjnouZ6rKMnP30H+CG4Ya5uouM/Sv5flgJ+1VnZo/kB89hQ4CELr3bBfxSW4lCS1Tmg/z8w059D2nsn7wiMols3Qgw4FJu773K03fyLGoV4JshxA9lvnLt/Vy+azDNEBP5drQeQ7l8GMrLAPIEN8oGbuH9+TyYoxj0P38Kx4hzlW3owGs1U2+wCuYCq2b58oGTYonKnynFV4Pi8f94uBWd6ziIJoKhwx6MsJzKIt/6T91QWjWozOpF9uGy81ZfR3WHU/gnIyWDTJsLnB7nFA5z9V3/K3Orj5tlVr7iZbCUhA9v6XMYTpyyxjoMtBjVad2IztaWXZIZ97Xx7WBkGS9lvFZIqgHMYERb/On/4bEEXdPlzyJxwwlPBNvPv7enVAsYjPJJ58CQ42fuYkMYZlNcTGfYz9Nw/K64ocMidfdMKvdFD1w6Cw/U1HkQ0SZssy6yEb1BpzdBfMbsUDnh0OJffUpeGp402XOwUNT4="

install:
- npm update --save false
- npm prune
- npm ci
- firefox -headless &

script:
- npm test
# check if the docs have been generated
- npm run docs
- test -z "$(git diff --name-only | grep '^doc/readme.md$')"

- npm run cover

after_success:
- bash <(curl -s https://codecov.io/bash)

jobs:
include:
- stage: publish
node_js: 10
script: echo -e "machine github.com\n login $GH_TOKEN" >> ~/.netrc && npm run release
node_js: 14
script: npx semantic-release
142 changes: 80 additions & 62 deletions README.md
Original file line number Diff line number Diff line change
@@ -3,57 +3,62 @@
The official Smartcar Node SDK.

## Overview

The [Smartcar API](https://smartcar.com/docs) lets you read vehicle data
(location, odometer) and send commands to vehicles (lock, unlock) using HTTP requests.

To make requests to a vehicle from a web or mobile application, the end user
must connect their vehicle using
[Smartcar's authorization flow](https://smartcar.com/docs#authentication).
[Smartcar Connect](https://smartcar.com/docs/api#smartcar-connect).
This flow follows the OAuth spec and will return a `code` which can be used to
obtain an access token from Smartcar.

The Smartcar Node SDK provides methods to:
1. Generate the link to redirect to for Smartcar's authorization flow.
2. Make a request to Smartcar with the `code` obtained from this authorization
flow to obtain an access and refresh token

1. Generate the link to redirect to Connect.
2. Make a request to Smartcar with the `code` obtained from Connect to obtain an
access and refresh token
3. Make requests to the Smartcar API to read vehicle data and send commands to
vehicles using the access token obtained in step 2.
vehicles using the access token obtained in step 2.

Before integrating with Smartcar's SDK, you'll need to register an application
in the [Smartcar Developer portal](https://developer.smartcar.com). If you do
not have access to the dashboard, please
[request access](https://smartcar.com/subscribe).

### Flow
* Create a new `AuthClient` object with your `clientId`, `clientSecret`,
`redirectUri`, and required `scope`.
* Redirect the user to Smartcar's authentication flow using `getAuthUrl` or one
of our frontend SDKs.
* The user will login, and then accept or deny your `scope`'s permissions.
* Handle the get request to `redirectUri`.
* If the user accepted your permissions, `req.query.code` will contain an
authentication code.
* Use `exchangeCode` with this code to obtain an access object
containing an access token (lasting 2 hours) and a refresh token
(lasting 60 days).
* Save this access object.
* If the user denied your permissions, `req.query.error` will be set
to `"access_denied"`.
* If you passed a state parameter to `getAuthUrl`, `req.query.state` will
contain the state value.
* Get the user's vehicles with `getVehicleIds`.
* Create a new `Vehicle` object using a `vehicleId` from the previous response,
and the `access_token`.
* Make requests to the Smartcar API.
* Use `exchangeRefreshToken` on your saved `refreshToken` to retrieve a new token
when your `accessToken` expires.

- Create a new `AuthClient` object with your `clientId`, `clientSecret`,
`redirectUri`.
- Redirect the user to Smartcar Connect using `getAuthUrl` with required `scope` or with one
of our frontend SDKs.
- The user will login, and then accept or deny your `scope`'s permissions.
- Handle the get request to `redirectUri`.
- If the user accepted your permissions, `req.query.code` will contain an
authorization code.
- Use `exchangeCode` with this code to obtain an access object
containing an access token (lasting 2 hours) and a refresh token
(lasting 60 days).
- Save this access object.
- If the user denied your permissions, `req.query.error` will be set
to `"access_denied"`.
- If you passed a state parameter to `getAuthUrl`, `req.query.state` will
contain the state value.
- Get the user's vehicles with `getVehicles`.
- Create a new `Vehicle` object using a `vehicleId` from the previous response,
and the `access_token`.
- Make requests to the Smartcar API.
- Use `exchangeRefreshToken` on your saved `refreshToken` to retrieve a new token
when your `accessToken` expires.

### Installation

```shell
npm install smartcar --save
```

### Example

```javascript
'use strict';

@@ -65,24 +70,22 @@ const app = express();
const port = 4000;

const client = new smartcar.AuthClient({
clientId: 'SMARTCAR_CLIENT_ID',
clientSecret: 'SMARTCAR_CLIENT_SECRET',
redirectUri: 'YOUR_CALLBACK_URI',
scope: ['read_vehicle_info'],
development: true, // include "mock" Smartcar brand in make selector for testing
clientId: '<Smartcar Client Id>', // fallback to SMARTCAR_CLIENT_ID ENV variable
clientSecret: '<Smartcar Client Secret>', // fallback to SMARTCAR_CLIENT_SECRET ENV variable
redirectUri: '<Your callback URI>', // fallback to SMARTCAR_REDIRECT_URI ENV variable
mode: 'test', // launch Smartcar Connect in test mode
});

// Redirect to Smartcar's authentication flow
// Redirect to Smartcar Connect
app.get('/login', function(req, res) {

const link = client.getAuthUrl({state: 'MY_STATE_PARAM'});
const link = client.getAuthUrl(['read_vehicle_info']);

// redirect to the link
res.redirect(link);
});

// Handle Smartcar callback with auth code
app.get('/callback', function(req, res, next) {
app.get('/callback', async function(req, res, next) {
let access;

if (req.query.error) {
@@ -91,31 +94,26 @@ app.get('/callback', function(req, res, next) {
}

// exchange auth code for access token
return client.exchangeCode(req.query.code)
.then(function(_access) {
// in a production app you'll want to store this in some kind of persistent storage
access = _access;
// get the user's vehicles
return smartcar.getVehicleIds(access.accessToken);
})
.then(function(res) {
// instantiate first vehicle in vehicle list
const vehicle = new smartcar.Vehicle(res.vehicles[0], access.accessToken);
// get identifying information about a vehicle
return vehicle.info();
})
.then(function(data) {
console.log(data);
// {
// "id": "36ab27d0-fd9d-4455-823a-ce30af709ffc",
// "make": "TESLA",
// "model": "Model S",
// "year": 2014
// }

// json response will be sent to the user
res.json(data);
});
const tokens = await client.exchangeCode(req.query.code);
// get the user's vehicles
const vehicles = await smartcar.getVehicles(tokens.accessToken);
// instantiate first vehicle in vehicle list
const vehicle = new smartcar.Vehicle(
vehicles.vehicles[0],
tokens.accessToken
);
// get identifying information about a vehicle
const attributes = await vehicle.attributes();
console.log(attributes);
// {
// "id": "36ab27d0-fd9d-4455-823a-ce30af709ffc",
// "make": "TESLA",
// "model": "Model S",
// "year": 2014
// "meta": {
// "requestId": "ada7207c-3c0a-4027-a47f-6215ce6f7b93"
// }
// }
});

app.listen(port, () => console.log(`Listening on port ${port}`));
@@ -127,17 +125,37 @@ For detailed documentation on parameters and available methods, please refer to
the [SDK Reference](doc/readme.md).

## Contributing

To contribute, please:

1. Open an issue for the feature (or bug) you would like to resolve.
2. Resolve the issue and add tests in your feature branch.
3. Open a PR from your feature branch into `master` that tags the issue.
3. Open a PR from your feature branch into `develop` that tags the issue.

To test:

```shell
npm run test
```

Note: In order to run tests locally the following environment variables would have to be set :

- `E2E_SMARTCAR_CLIENT_ID` - Client ID to be used.
- `E2E_SMARTCAR_CLIENT_SECRET` - Client secret to be used.
- `E2E_SMARTCAR_AMT` - AMT from dashboard for webhooks tests.
- `E2E_SMARTCAR_WEBHOOK_ID` - Webhook ID use in the webhook tests success case.
- `BROWSER` - Web browser for tests (`chrome` or `firefox`, default: `firefox`).


Your application needs to have https://example.com/auth set as a valid redirect URI

[ci-url]: https://travis-ci.com/smartcar/node-sdk
[ci-image]: https://travis-ci.com/smartcar/node-sdk.svg?token=jMbuVtXPGeJMPdsn7RQ5&branch=master
[npm-url]: https://badge.fury.io/js/smartcar
[npm-image]: https://badge.fury.io/js/smartcar.svg

## Supported Node.js Versions

Smartcar aims to support the SDK on all Node.js versions that have a status of "Maintenance" or "Active LTS" as defined in the [Node.js Release schedule](https://github.com/nodejs/Release#release-schedule).

In accordance with the Semantic Versioning specification, the addition of support for new Node.js versions would result in a MINOR version bump and the removal of support for Node.js versions would result in a MAJOR version bump.
2 changes: 1 addition & 1 deletion doc/.template.hbs
Original file line number Diff line number Diff line change
@@ -11,4 +11,4 @@ Smartcar Node SDK documentation.
{{/if}}
{{/indexChildren}}

{{>main}}
{{>main}}
Loading