Remove device via cloud API

Hi all

I’m trying to figure out how to remove a device from a user via the cloud API. I notice the JS SDK has a remove function but the HTTP based cloud API doesn’t seem to have one? Any ideas?

Make a request to DELETE /v1/devices/:deviceId to remove a device.

1 Like

Thanks @jvanier I’ll give that a go now.

Were you able to get this to work? I’ve been unsuccessful at getting the cloud api or the javascript version to work. It looks like it works…but the device still shows up for the customer when querying with spark.listDevices() for the logged in user (via javascript sdk).

curl -X DELETE https://api.particle.io/v1/devices/DEVICE_ID -d access_token=123123123

Response:

{
  "ok": true
}

In addition I have tried to remove the device directly via the javascript SDK, but get an error:

spark.getDevice(id, function(err, device) {
       device.remove(function(err, data) {
           console.log('device.remove err:', err);
           console.log('device.remove data:', data);
      });
 });

Error:

XMLHttpRequest cannot load https://api.spark.io/v1/devices/DEVICE_ID. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:63342' is therefore not allowed access. The response had HTTP status code 400.

Hi @1inarow

Yip it worked for me, the JS library is out of date I believe, although a newer one is on it’s way by the looks of things on GitHub. Your curl request looks ok I think. This is how I do it in AJAX:

var jqxhr = $.ajax({
  type: "DELETE",
  url: "https://api.particle.io/v1/devices/"+[DEVICE_ID],
  data: {
    access_token: accessToken,
}
})

You’re sure the access token you’re using is the one that ‘owns’ the device?

Hi @G65434_2

I am getting a success when I do it via ajax as well: {ok: true}. However, when I subsequently run spark.listDevices() that device still shows up in the returned array. Maybe I’m doing something funny, but here is the entire process that I have:

  1. Implement two legged authentication where I create an access token for a new user (server side).
  2. Log that user in locally (using sparkjs-0.5.9 javascript) via spark.login({accessToken: ACCESS_TOKEN}) where the access token is the one gained from step #1
  3. Get a claim code via https://api.particle.io/v1/orgs/ORG_SLUG/products/PRODUCT_SLUG/device_claims. I do this server side, but have also done it with ajax client side.
  4. Claim the device using the softap js (browserfied) via setClaimCode when connected to the device in listening mode
  5. Device claims sucessfully and then shows up when I run spark.listDevices()
  6. Remove device using the same token acquired in step #1, and the result is as above: {ok: true}
  7. Run spark.listDevices() still shows the device…but it should then be removed right?

Hi @1inarow

Hmm, everything you’re doing seems ok to me, however I didn’t do two legged auth in my setup so I’m not 100% sure. Wouldn’t have thought that would have made any difference. I’ll ping @jeiden as he is knowledgeable in this area!

@jeiden - any idea what might be going on here? I’d like to “unclaim” the devices that I have for development, because while they are claimed by a customer I cannot deploy / build to them without releasing a firmware to the dashboard and locking and flashing from there.

Hey @1inarow,

Good question, that makes total sense why that would be confusing. I know what’s going on here. That endpoint, DELETE https://api.particle.io/v1/devices/DEVICE_ID was built to be used for unclaiming a user device, not a customer device.

As a product creator implementing two-legged auth, I would assume that the device in question is owned by a customer, and not a user. As such, the endpoint returns a 200 without unsetting the customer ID. Admittedly, the product creator architecture is relatively new, and for most of our existence only users existed, not customers. We need to do a better job of both communicating what endpoints are for users vs. customers, as well as providing feature pairity between these two entities.

I will say, though, that unclaiming a device owned by a customer has some security implications and we purposefully punted on it. Think about it – a real customer in the wild who owns your product would likely be infuriated if the company that sold them their widget had the ability to lock them out from using their product remotely (this is what would happen if it was unclaimed).

We need to collectively brainstorm about a way to give you as the product creator the control you need while developing, while also protecting the privacy of the customer. It’s a delicate issue.

In the meantime, if you are sure that this is a device being used for development purposes, you can send me an email at jeff@particle.io with the device ID and I will unclaim the device for you.

Does this all make sense?

Hope this helps,

Jeff

This makes a lot of sense and would explain why I cannot do very much with a customer. I will also agree that it does make development of claiming a device using a customer hard, because I will have to make a choice as to whether or not to use customers at all. On the one hand I can leave the code in place that I know works for claiming, but not test it anymore and assume it will work in production. The other option is to not use customers at all and abstract the login and token process by pushing every touch point onto my remote server. That way every device is owned by me (parent account) and I publish all events and any data through my remote server. I can’t say that I’m very fond of either option and the second is definitely a lot of reworking on my end.

To all of the points about security that you make I will say that it does seem a bit odd that I [the sdk] can create a user (with email) and control everything about a device remotely, but I cannot either change the email or pass on ownership. The token is all that really matters in order to claim, push events, login etc and I create and have that.

In any case, I look forward to this process being completed and if in the mean time you need any testing or feedback please don’t hesitate. Thanks for the fast reply too btw. I will email you separately about the device ids.

1 Like

Hi @jeiden

I didn’t actually realise this was the case. I’m using customers as well and this will have some big implications on what I’m doing.
Perhaps I’m only seeing part of it, but I don’t completely buy the argument that a customer wouldn’t like knowing that they could be locked out. Anyone selling a product will likely want this control anyway, otherwise they could be constantly referring these requests onto Particle staff, using their time… After all, any product owner can effectively release a firmware update rendering a device useless so I don’t see much difference with having the ability to unclaim a customer device.
I have units on my desk at the moment that will be going out to customers soon. The way I see it is I can’t even run these through a test ‘customer account creation and claiming process’ without then asking you to release them all? Any updates on your brainstorm when it happens would be much appreciated!

Hi @G65434_2

I'm sure @jeiden will have more than I can offer, but the way that I resolved to do my system is to just avoid creating customers all together. Instead I am routing all of my commands up to my server to do the authentication with api.particle.io. That way I can remove any sort of client side logging in or polling of data through the spark (local) sdk.

As an example I need to see the status of a device, it's name etc. So, what I do is make a call to my server. The server in turn makes an http request to the Particle Cloud API and returns the appropriate data back to the client. I even verify during the request that that device "belongs" to the caller requesting the information in my database. It does seem like a little bit more work, but it avoids the whole claim code / ownership of the device completely. Honestly, it works really well and very fast too.

I can get all devices like this (restful get) and then cross reference the result against my database of devices and use the primary access token (securely stored on the server) to make the call:

https://api.spark.io/v1/devices?access_token=123123123

or a single device like (restful get):

https://api.spark.io/v1/devices/[DEVICE_ID]/?access_token=123123123

You can call functions and even listen to event streams server side - full documentation on cloud api.

I'm not sure that helps you, but it's definitely a viable solution if you have a two legged approach with a server in the middle as it is.

Thanks @1inarow

It’s actually a good point. I hadn’t considered that as a possibility.
The one concern for me is that I’m only serving static pages at the moment. I’m not a web developer and the two legged approach, while I’m sure I’d get there in the end is time spent that I can’t really afford at the moment!

I imagine you’ve used some sort of server side language like PHP or Node?

Hi again @jeiden

Sorry to bother you again with this but do I understand correctly that there is no way to ‘unclaim’ a device after a customer has claimed it? Even from a customers perspective (e.g. delete request using customers access token etc.)

Despite the good suggestions from 1inarow, I don’t have the time yet to implement a two legged auth yet, and just want to gain a better understanding of what’s possible here.

Thanks :smile:

@1inarow and @G65434_2

I realize that not being able to unclaim a customer’s device is really a detriment to the development process. I’m going to look into a solution to this today.

Jeff

Thanks very much @jeiden, I really appreciate your fast responses.

That’s great! Thanks @jeiden !

hi @jeiden do you have any news about customer’s device unclaiming? i think it’s very
important not only during the development process but also for giving the right support to the customer. i’m developing some products as custom shields for the photon and i can imagine a scenario where the customer has some problems with my product: he can send it back to me and get a new one (with a new photon). after receiving it i notice that the photon is ok so i could use it in another product for another customer. how can i do in this case?

5 Likes

I need it too!!!