particle-api-js 10.4.3 → 10.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "particle-api-js",
3
- "version": "10.4.3",
3
+ "version": "10.5.0",
4
4
  "description": "Particle API Client",
5
5
  "main": "src/Particle.js",
6
6
  "scripts": {
package/src/Particle.js CHANGED
@@ -3,17 +3,6 @@ const EventStream = require('./EventStream');
3
3
  const Agent = require('./Agent');
4
4
  const Client = require('./Client');
5
5
 
6
- // Hack to avoid importing the type on every @return statement
7
- /**
8
- * @typedef {import('./Agent').RequestResponse} RequestResponse
9
- */
10
- /**
11
- * @typedef {import('./Agent').RequestError} RequestError
12
- */
13
- /**
14
- * @typedef {import('./Agent').Auth} Auth
15
- */
16
-
17
6
  /**
18
7
  * Particle Cloud API wrapper.
19
8
  *
@@ -22,7 +11,12 @@ const Client = require('./Client');
22
11
  *
23
12
  * Most Particle methods take a single unnamed argument object documented as
24
13
  * `options` with key/value pairs for each option.
14
+ *
15
+ * @typedef {import('./Agent').RequestResponse} RequestResponse
16
+ * @typedef {import('./Agent').RequestError} RequestError
17
+ * @typedef {import('./Agent').Auth} Auth
25
18
  */
19
+ // These typedef avoid importing the type on every @return statement
26
20
  class Particle {
27
21
  /**
28
22
  * Contructor for the Cloud API wrapper.
@@ -243,7 +237,7 @@ class Particle {
243
237
  * @param {String} options.username Email of the new user
244
238
  * @param {String} options.password Password
245
239
  * @param {String} options.accountInfo Object that contains account information fields such as user real name, company name, business account flag etc
246
- * @param {Object} [options.utm] Object that contains info about the campaign that lead to this user creation
240
+ * @param {Object} [options.utm] Object that contains info about the campaign that lead to this user creation
247
241
  * @param {Object} [options.headers] Key/Value pairs like `{ 'X-FOO': 'foo', X-BAR: 'bar' }` to send as headers.
248
242
  * @param {Object} [options.context] Request context
249
243
  * @returns {Promise} A promise
@@ -669,6 +663,42 @@ class Particle {
669
663
  return this.put({ uri, auth, headers, data, context });
670
664
  }
671
665
 
666
+ /**
667
+ * Disable device protection.
668
+ *
669
+ * @param {Object} options Options for this API call.
670
+ * @param {String} options.deviceId Device ID or name.
671
+ * @param {String} options.action Request action: `prepare` or `confirm`.
672
+ * @param {String} [options.org] Organziation ID or slug.
673
+ * @param {String} [options.product] Product ID or slug.
674
+ * @param {String} [options.serverNonce] Base64-encoded server nonce. Mandatory if `action` is `confirm`,
675
+ * @param {String} [options.deviceNonce] Base64-encoded device nonce. Mandatory if `action` is `confirm`,
676
+ * @param {String} [options.deviceSignature] Base64-encoded device signature. Mandatory if `action` is `confirm`,
677
+ * @param {String} [options.devicePublicKeyFingerprint] Base64-encoded fingerprint of the device public key.
678
+ * Mandatory if `action` is `confirm`,
679
+ * @param {Auth} [options.auth] Access token or basic auth object. Can be ignored if provided in constructor.
680
+ * @param {Object} [options.headers] Key/value pairs to send as headers.
681
+ * @param {Object} [options.context] Request context.
682
+ * @returns {Promise} A promise
683
+ */
684
+ unprotectDevice({ deviceId, org, product, action, serverNonce, deviceNonce, deviceSignature, devicePublicKeyFingerprint, auth, headers, context }) {
685
+ const data = { action };
686
+ if (deviceNonce !== undefined) {
687
+ data.device_nonce = deviceNonce;
688
+ }
689
+ if (serverNonce !== undefined) {
690
+ data.server_nonce = serverNonce;
691
+ }
692
+ if (deviceSignature !== undefined) {
693
+ data.device_signature = deviceSignature;
694
+ }
695
+ if (devicePublicKeyFingerprint !== undefined) {
696
+ data.device_public_key_fingerprint = devicePublicKeyFingerprint;
697
+ }
698
+ const uri = this.deviceUri({ deviceId, product, org }) + '/unprotect';
699
+ return this.put({ uri, data, auth, headers, context });
700
+ }
701
+
672
702
  /**
673
703
  * Provision a new device for products that allow self-provisioning
674
704
  * @param {Object} options Options for this API call
@@ -714,16 +744,6 @@ class Particle {
714
744
  });
715
745
  }
716
746
 
717
- changeProduct({ deviceId, productId, auth, headers, context }){
718
- return this.put({
719
- uri: `/v1/devices/${deviceId}`,
720
- auth,
721
- headers,
722
- data: { product_id: productId },
723
- context
724
- });
725
- }
726
-
727
747
  /**
728
748
  * Get the value of a device variable
729
749
  * @param {Object} options Options for this API call
@@ -2639,11 +2659,18 @@ class Particle {
2639
2659
  * @param {Object} options Options for this API call
2640
2660
  * @param {String} options.deviceId Device ID to access
2641
2661
  * @param {String} [options.product] Device only in this product ID or slug
2662
+ * @param {String} [options.org] Device only in this organization ID or slug
2642
2663
  * @private
2643
2664
  * @returns {string} URI
2644
2665
  */
2645
- deviceUri({ deviceId, product }){
2646
- return product ? `/v1/products/${product}/devices/${deviceId}` : `/v1/devices/${deviceId}`;
2666
+ deviceUri({ deviceId, product, org }){
2667
+ if (org) {
2668
+ return `/v1/orgs/${org}/devices/${deviceId}`;
2669
+ }
2670
+ if (product) {
2671
+ return `/v1/products/${product}/devices/${deviceId}`;
2672
+ }
2673
+ return `/v1/devices/${deviceId}`;
2647
2674
  }
2648
2675
 
2649
2676
  /**
@@ -817,19 +817,6 @@ describe('ParticleAPI', () => {
817
817
  });
818
818
  });
819
819
 
820
- describe('.changeProduct', () => {
821
- it('generates request', () => {
822
- return api.changeProduct(props).then(Common.expectDeviceUrlAndToken);
823
- });
824
-
825
- it('sends proper data', () => {
826
- return api.changeProduct(props).then(({ data }) => {
827
- data.should.be.instanceOf(Object);
828
- data.product_id.should.equal(props.productId);
829
- });
830
- });
831
- });
832
-
833
820
  describe('.getVariable', () => {
834
821
  describe('user scope', () => {
835
822
  it('generates request', () => {
@@ -2901,6 +2888,32 @@ describe('ParticleAPI', () => {
2901
2888
  });
2902
2889
  });
2903
2890
  });
2891
+
2892
+ describe('.unprotectDevice', () => {
2893
+ it('generates request', () => {
2894
+ return api.unprotectDevice(Object.assign({}, propsWithProduct, {
2895
+ action: 'action',
2896
+ deviceNonce: 'device-nonce',
2897
+ serverNonce: 'server-nonce',
2898
+ deviceSignature: 'device-signature',
2899
+ devicePublicKeyFingerprint: 'device-public-key-fingerprint'
2900
+ })).then((results) => {
2901
+ results.should.match({
2902
+ method: 'put',
2903
+ uri: `/v1/products/${product}/devices/${props.deviceId}/unprotect`,
2904
+ auth: props.auth,
2905
+ headers: props.headers,
2906
+ data: {
2907
+ action: 'action',
2908
+ device_nonce: 'device-nonce',
2909
+ server_nonce: 'server-nonce',
2910
+ device_signature: 'device-signature',
2911
+ device_public_key_fingerprint: 'device-public-key-fingerprint'
2912
+ }
2913
+ });
2914
+ });
2915
+ });
2916
+ });
2904
2917
  });
2905
2918
 
2906
2919
  describe('backwards-compatibility function aliases', () => {
@@ -2922,6 +2935,12 @@ describe('ParticleAPI', () => {
2922
2935
  uri.should.equal('/v1/products/xyz/devices/abc');
2923
2936
  });
2924
2937
  });
2938
+ describe('org scope', () => {
2939
+ it('gets the org device uri', () => {
2940
+ const uri = api.deviceUri({ deviceId: 'abc', org: 'xyz' });
2941
+ uri.should.equal('/v1/orgs/xyz/devices/abc');
2942
+ });
2943
+ });
2925
2944
  });
2926
2945
 
2927
2946