Customers - claiming and unclaiming

@G65434_2 I’m actually doing things a bit differently because I have the two legged approach. I have the user create a username and password for the back end system that I then manage. Once a user is saved to the database I have the server make a call to get a token from particle.io and save that to the user’s account as well. So, when the user logs in they actually log in to my system and then I retrieve their token and log them into particle with that.

Here’s a curl call for creating the new customer without a password:

curl 
-X POST 
-u "[org user]:[org secret]" 
-d email="[customer email]" 
-d no_password=true 
https://api.particle.io/v1/orgs/[org slug]t/customers

To create a token for an existing customer you have to do it a little different, but it’s still just as easy:

curl 
-X POST 
-u "[org user]:[org secret]" 
-d grant_type=client_credentials 
-d scope=customer="[customer email]" 
https://api.particle.io/oauth/token

Also, i usually have it try the new customer first and then fallback to creating it based on an existing customer. The reason being is that in development I try and try again with the same email and once a customer is created in particle.io you can’t really delete it, but rather get a new token.

So, once I’ve got the token that’s returned by either of the above calls, I use:

spark.login({accessToken: [access token from customer]}).then(function()
            {
                console.log("Logged into particle");

                // See below on getting a claim code
                var sap = new SoftAPSetup();
                sap.setClaimCode([claim code], callback);
                function callback(err, dat)
                {
                if(err)
                {
                    throw err;
                }
                // I forget what this returns, but it should be an object with a success identifiable in it
                console.log(dat);
            }
            });
        }

Since it’s not above, here is how you get a claim code:

curl 
    -X POST 
    -d access_token=[your orgs access token / secret]
    https://api.particle.io/v1/orgs/[org slug]/products/[product slug]/device_claims 

You can do all of the curls above with a simple ajax call as well, I just test everything via curl first and have that better documented. Also, this code is pretty piecemealed together so let me know if something doesn’t work. Oh, also, when you do the ajax calls, you will probably have to base64 encode them and may have to include some additional headers to get them to work. I had to, but I’m doing it server side, so maybe it’s different.

Hope this helps!

After writing that response I realized it doesn’t really satisfy your needs as its a two legged approach. I’ll do a particle only version when I get back to it - don’t have time right this second. In the mean time you can always use the cloud api to log them in vs the spark.login().

Try the implicit way here:
https://docs.particle.io/reference/api/#create-a-customer---implicit

Hi @1inarow

No worries, I do really appreciate your notes about the two-legged approach. It no doubt has it’s benefits and it’s something I might consider down the track, it’s just a bit outside the scope of my skills at the moment.

I believe I’m already creating customers correctly, I also (think) my softAP page is pretty much correct. At the moment my problem seems to be that I can only claim devices that have previously been claimed to my ‘user’ account.
This is making me think I have got the login process incorrect and that the access token generated by my login post (above) is in the scope of the particle-api client. I’m not sure what however I should be replacing client_id and client_secret with.
It was my understanding that the client_secret should never be exposed, so placing it an HTML form or JS file does not seem correct.
I have tried setting both client_id and client_secret to my webapp client id (webdashboard-XXXX) and I can login, however I still cannot successfully claim a product.
Furthermore I have tried setting client_secret to my actual secret as well which results in a failed login.

@zachary Just pinging you here as think you may be able to help now that I think I’m closer to the root cause.

I suspect now that my problem is not to do with the softAP process, but the way that I log customers into my dashboard.

To confirm, I’m using implicit grant flow. I create customer using the process here: https://docs.particle.io/reference/api/#create-a-customer---implicit

This all works fine and a customer is created. What I’ve realised now is that I can’t log a customer in using this client_id as it’s scoped only for customer creation.

I previously hadn’t even realised this was a problem as I was still using ‘particle-api’ for both client_id and client_secret (please see screen shot above)

This has actually worked fine up until now, which I suspect is now causing a problem because the access token created when logging in via the particle-api client is not scoped for claiming my product. Is this correct?

My question now is, can I not call functions, list devices etc. unless I have a full oauth client with no scope restrictions? If this is the case, is it possible to have a statically served web app that uses a full access oauth client and does not expose the client secret?

@kefir135 I’m not sure where you are in your app progress but some of this may interest you.

@G65434_2

I was unable to get this to work btw. I created a basic page with the default spark.login and logged a user in with un/pw. Then I got a claim code via ajax call to https://api.particle.io/v1/device_claims passing in the token I got at login. I passed the claim code into the softap.setClaimCode method but always get back {r:0} and the device doesn’t seem to be claimed. No matter how many times I claim or unclaim the device using different accounts via CLI and then try to claim it using the softap method it’s always the same. I’m not using customers in my test instance, but according to the documentation it should work in the softAP way…but then again it also mentions the Electron’a imei and iccid, so maybe it’s not right.

I have the full html if you need it to compare.

Also, as good practice, I would not include your primary particle token or username in any released source code. I would keep that hidden behind a server at least. If those were obtained, someone could unclaim and reclaim all of your fleet and push their own firmware etc.

Thanks for having a go!

Are you using the spark-api.js? When you create the SparkApi object, are you setting your clientId and clientSecret parameters?
I’m not currently using any of the JS libraries (apart from the softAP one). I wanted to get a good understanding of the HTTP API, plus the JS library has only recently caught up by the looks of things.

My softAP is working. I’ve definitely claimed products with it, just having trouble with some of them.

I wasn’t intending to include any tokens or usernames in my source, users will login via HTTPS hence their access token will be visible to them but on one else.

Hi, so my progres so far:

I created an OAuth client, then I created a part of an app for creating customers accounts, according to your quick tutorial.
Than, I tested it - created a customer.
At this point, I wanted to test this customer account.
It doesn’t allow to log into a dashboard, and it doesn’t allow to log into the Build (web editor) - which is correct :smile:
However, it DOES allow to login into a mobile Particle app. So I logged in, and used one of my spare photons, to be claimed using this particle account. I previously imported the same Photon into my product, using a dashboard. And everything worked perfectly so far - I could see the customer account in the dashboard, associated with the just claimed photon.
I did this second time, just to be sure, with another account and photon.
So far so good, I assumed the customer accounts to be created correctly.
Than, I wanted to test the claiming process using my app. So first I wanted to “unclaim” the two photons I used before.
And than the problems started - it’s basically impossible.
I can’t delete the photon from the dashboard - a get “bumper - you can’t delete the photon which is not owned by a member of your organization”. Of course, my customer is not a member of the organization. So, I tried to claim the photon, with the API (using curl), using a normal account (member of the organization), using the “request_transfer=true” flag, which is exactly for claiming photons already claimed by another account. But, this didn’t work. So, I’m stuck with two photons, and I don’t have any more right now…
Waiting for the reply from Particle - they promised to give some answers today…

1 Like

@G65434_2 I used the spark-api.js and not just the cloud. I’m not actually creating a spark instance either. I’m doing this:

sparkLogin(function(data) {
      console.log(data);
      getClaimCode(data.access_token);
});

And then I do this:

var claim_code = "";
function getClaimCode($accessToken)
{
    var jqxhr = $.ajax({

        method: "POST",
        url: "https://api.particle.io/v1/device_claims",
        data: { "access_token": $accessToken }

    }).then(function( data, textStatus, jqXHR ) {
        console.log("Sucessfully got claim code");
        console.log(data);
        claim_code = data.claim_code;
        $("#sendClaimButton").show(); // just a button to send the code now that I have it
        // Now switch to a device in listening mode and attempt to claim it by clicking the button
    }, function( jqXHR, textStatus, errorThrown ) {
        console.log("Failed to get a claim code");
        console.log(textStatus);
        console.log(errorThrown);
    });
}
// Bind a button
$("#sendClaimButton").bind("click", sendClaimClick);

Then of course the SoftAP

function sendClaimClick()
    {
        var sap = new SoftAPSetup();
        sap.setClaimCode(claim_code, callback);
        function callback(err, dat)
        {
            if(err)
            {
                throw err;
            }
            console.log(dat); // currently only outputs {r:0}
        }
    }

That’s pretty much all of it sans the html for the button and js includes for jQuery and particle files. It doesn’t include any keys or tokens either and as far as I can tell should work. Again, the above doesn’t use customers. As a note, I to have a complete system of claiming devices using the cloud api, but I have to use my parent / company account’s tokens to get this to work since I do create customers. I’ve not had any issues claiming any photons with it either.

@kefir135 that is true, you cannot currently unclaim a device using any of the api’s (cloud, js or native). You have to email someone at Particle directly to take care of this, until it’s completed.

Ok, could someone from Particle please give us something to work with here? @Dave, @zachary @bryce?
I realize the electron is high priority at the moment but this is existing functionality that has been promised for a long time. There are multiple sections of the docs that say more information is coming in Aug 2015… I’m not one to complain and what you guys are doing is awesome but I’m literally 24 hours away from installing my first product with a customer and I need to know if I’m going to have to tell them that they can’t claim it and use it yet. Which isn’t a great start.
I realise some of the above questions may be a bit elementary, I’m not a web developer and I’m not asking to be walked through this, I simply want answers to a couple of questions:

-Does {r: 0} represent a failure or success in the softAP library? My understanding was that it indicated success…

-What client credentials should we login with when building a web app based on implicit grant flow? The docs mention plenty on creating customers and restricting scope to creating customers but nothing on how to log customers in… I realise the JS API does this but it still requires client_id and client_secret parameters…

-When will unclaiming customer devices be available? There are at least 4 people that I know of needing this functionality ASAP and without it, it makes testing the customer softAP process even more difficult

0 is success.

As mentioned on https://docs.particle.io/reference/api/#create-a-customer---implicit when creating a customer using implicit flow, it will also automatically login the customer and the customer access token will be appended as a hash to the redirect URI associated with the client credentials provided.

Further customer logins can be processed the same way as user logins, using any value (e.g. particle:particle) for client credentials.

Very soon. In the meantime, contact hello@particle.io and they can direct the request to an engineer to help unclaim it.

Thankyou very much for your answer @bryce - that clears a few things up. Are you aware of anyone that has managed to to claim a customer device (not a user device) using the current SoftAP JS library?

SoftAP and the firmware is ignorant of whether a claim code is for a user or a customer. If you PM me your deviceID and maybe the claim code used, I can take a look at our logs to see what might be going on.

1 Like

I can confirm the claim is now working, thanks to @bryce for letting me know that products are unable to be claimed before they are imported into the dashboard. Thanks Bryce!

I’m logging in as per usual with both client_id and client_secret set to particle-api (particle:particle as suggested above didn’t seem to work).

If anyone else has trouble with this, let me know and I may be able to provide code etc.

@bryce

I have a few quick followups questions to that solution. First of all, I can also confirm that once a device is in the dashboard it works no problem claiming via the customer route.

  1. Does this mean that we must use the dashboard for the customer flow? The dashboard is a paid tool, but there doesn’t seem to be any way to import them without it.
  2. Once a device is claimed it always shows as claimed via the SoftAP, even if I unclaim it using the CLI.
  3. In addition to #2 once it’s claimed I always get the {r:0} response no matter what I send it in the setClaimCode SoftAP method. i.e. I’m just sending it “123abc” and it returns {r:0}.

In questions 2 and 3 I’m not using the customer flow, but the full particle user flow. I assumed this was already working because I could unclaim a device with the CLI and through build.particle.io.

Thanks!

1 Like

Just to close the loop here – what ultimately solved @G65434_2’s issue was the fact that in our database, each the device did not have the correct product_id. Instead of having the ID of @G65434_2’s product, each device still was classified as a dev kit (For @G65434_2, he’s using P1s which have a product_id of 10 ). So, when the device was publishing it’s claim code generated for the product, our cloud checked the device record and saw it was still a dev kit, and rejected the request to claim.

To change the product_id of a given device to identify as your product, you must indicate to Particle that you want to change the device from being a dev kit (a Photon, P1, or Electron) to your product. To do this, you need to import the device into your Devices list on your organization’s dashboard, and check the box for “Force imported devices to switch to this product” (See below). Read here for more details: https://docs.particle.io/guide/how-to-build-a-product/dashboard/#adding-devices

Checking this box will ensure that the product_id is changed correctly. Now that the product_id is correct, the attempt to claim will work.

I’m sure you’re wondering…so I have to import and check this box for all my devices forever and ever? The answer is no, not at scale. If (and hopefully when!) your product reaches scale, and you are manufacturing large quantities of units, you will work with Particle to provision the devices in our cloud as your product. This will mean from the get-go, your Particle modules will be associated with the correct ID, and will not need to be imported from the dashboard. If you think you’re getting close to this point, contact sales@particle.io.

1 Like

@1inarow to answer your questions:

  1. No, you technically don’t need to use the dashboard to have a product with customers. The API endpoints are available to you without using the interface. It will just make your life easier by providing a UI on top of our API endpoints. There are some technicalities here to work through at this point, but it is possible.

  2. Customers (for the most part) should not really be using the CLI. They will be interacting with the device via your mobile or web app. The CLI is currently built for Particle users. In general, using the CLI to take action on customer’s devices is not really a good idea. In the future, I could see building a separate set of commands for developers/organization members who want to take action on a customer’s device via the CLI, but this is not currently available. If you try and claim a device as a customer from the CLI, it will assign the device a user_id not a customer_id (admittedly a bug on our end that we need to fix), and get your device into a strange state in which it can’t be controlled or unclaimed.

  3. {r: 0} simply means that the claim code was successfully sent to the device. It doesn’t mean that the claim was a success, it just means that the device received the code. Claiming happens in the cloud, not on the device. The claim code will get published to the cloud the next time the device connects, which will then attempt and claim the device to the user or customer that generated the claim code. You’re getting {r:0} back from the device because it is acknowleding that it received your claim code, it has no way of determining that the code is valid until it connects to the cloud

3 Likes

Thanks @jeiden! This clears up a lot for me and I’ll look into importing a device via the cloud api and not the dashboard, though I intend to use the dashboard in the time being for convenience.

p.s. I never intended to let end customers use the CLI. It was more of a way for me to describe my process and how I did it. Still a good answer and sorry for any confusion.

1 Like

Hey, just wanted to close out the loop here and let you know that customer unclaiming is now available via the Particle Dashboard. See this post for more details!

@1inarow Have you find the method even now, to import a device via api rather than importing into dashboard?

Maybe someone else can confirm this, but it looks as though your devices - those associated with your developer user account - are automatically brought into your dashboard - developer or organization.