Forum Discussion

fuenteso's avatar
fuenteso
Leader
9 years ago

Using HTTP PUT on an endpoint

Hi!

 

I've been trying to figure out how to edit a post directly from an endpoint. I not quite familiar with HTTP request over javascript, and the documentation (Updating message using HTTP PUT) is not very clear to me.

 

I've tried a couple of things with jQuery, but it looks like jQuery is not available on endpoints. I also tried pure javascript (XMLHttpRequest) but I'm not getting any results.

 

This is what I used:

<script type="text/javascript" language="JavaScript">
var data = {"data": {"type": "message","subject": "hello world","body": "this is the edited message post."}};
xhr = new XMLHttpRequest();

xhr.open('POST',encodeURI('http://api.lithium.com/community/2.0/<mycommunityID>/messages/5909'));
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.onreadystatechange = function(aEvt) {
    if (xhr.readyState == 4) {
     if(xhr.status == 200)
      console.log(xhr.responseText);
     else
      console.log("Error loading page\n");
  }
};

xhr.send(encodeURI('data=' + data));

</script>

And I got this error:

"XMLHttpRequest cannot load http://api.lithium.com/community/2.0/psg/messages/5909. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin '<my stage URL>' is therefore not allowed access. The response had HTTP status code 503."

 

 

Anyone has any examples?

 

I would appreciate any help, Thanks!

  • DougS's avatar
    DougS
    9 years ago

    I meant you need to use an endpoint that is hosted outside of the community to make the back-channel access token request. We currently restrict endpoints from calling .lithium.com domains for security reasons.

     

    If you are not able to host your own endpoint to make the access token request, you could try hitting the REST v1 messages/id/[message-id]/edit endpoint directly on the community (not through api.lithium.com) to make your message edit.

     

    -Doug

  • DougS's avatar
    DougS
    Khoros Oracle

    jQuery is not available in endpoints, since endpoint logic executes server-side (unless you are returning html with a script tag that runs the javascript, then you'll need to include a link to a jQuery script).

     

    If you want to make your call in the browser, you should be able to use jQuery if you use the liaAddScript directive in a custom component(you can find documentation for the liaAddScript directive in the freemarker documentation by clicking on Refer > Directives). You can use the jQuery lithium puts on the page by doing something like this (you'll need to tweak it a bit to make it work):

     

    <@liaAddScript>
        ;(function($) {
         $.ajax({
           method: 'put',
           url: 'https://api.lithium.com/community/2.0/${myCommunityId}/messages/5909',
    headers: {
    'client-id': '${clientId}'
    'authorization': 'Bearer ' + $.cookie('litok');
    }, data&colon; { 'data': { 'type': 'message', 'subject', 'my changed subject' } }, dataType: 'json', beforeSend: function (jqXHR, settings) { $(this).addClass('loading'); }, success: function (data) { if (data.status == 'success') { // do something with data }, error: function (jqXHR, textStatus, errorThrown) { $('body').trigger('displayModalError', ["${text.format("error.exception.title")}"]); }, complete: function(jqXHR, textStatus) { $(this).removeClass('loading'); } }); })(LITHIUM.jQuery); </@liaAddScript>
    • fuenteso's avatar
      fuenteso
      Leader

      Thanks DougS,

       

      Looks like my problem is that I don't have the oauthAccessToken. I think I'm almost there, using the endpoint and plain javascript I was able to get the 'autorization_code', but when I do the POST /accessToken call I'm getting an internal server error.

       

      I'm working with an endpoint because I don't need to display anything on our community. I'm working on an automated way to replace broken links on our community, so basically I'm pulling the content then using javascript to make the replacements and now I'm trying to write the message body back to the community.

       

      Here's what I'm doing.

       

      1. I'm using an XMLHttpRequest to send the GET /authorize request. I'm using a dummy redirect_uri because I want to do all the processing on the same endpoint, so I'm getting the authorization code from the 'responseURL'

      2. I'm using that authorization code for the POST /accessToken request but I keep getting a 'Internal server error' ({"status":"Internal Server Error","message":"Internal Server Error","statusCode":500}) -not very descriptive-

       

      var requestBody = {"client_id" : "<my client ID>",
                        "client_secret" : "<my client secret>",
                        "code" : authorization_code,
                        "redirect_uri" : "http://<my stage community URL>/",
                        "grant_type" : "authorization_code",
                        "state" : "someUniqueInfoAboutTheState"};
      
      xhr2 = new XMLHttpRequest();
      xhr2.open('POST',encodeURI('https://api.lithium.com/auth/v1/accessToken'),true);
      xhr2.setRequestHeader('Content-Type', 'application/json');
      xhr2.setRequestHeader('client-id', '<my client ID>');
      
      xhr2.onload = function(aEvt) {    
           if(xhr2.status == 200) {        
              console.log("Response URL  = " + xhr2.responseURL);        
            }
           else {      
            console.log("Error loading page\n");    
          }  
      };
      
      xhr2.send(JSON.stringify(requestBody));

      I'm decoding the authorization code before sending it.

       

      Any ideas?

      • DougS's avatar
        DougS
        Khoros Oracle

        I forgot in my previous reply to mention that you need to include the client id (either as the client_id request parameter or as the client-id header) when you are making any call to api.lithium.com.  (I'll update my original reply above to include a client-id header)

         

        Step 3 on the summary of the flow in the OAuth 2.0 authorization grant flow article says "Make a server-to-server call from your OAuth client via Lithium's API Proxy to the Authorization Service to get an access token and refresh token mapping to the authorized user."

         

        This means that the call to get the Access Token once you have the authorization code needs to be made server-side, via some logic that you host (otherwise you risk someone stealing your client secret). Also, any request to refresh the access token needs to be made server-side, via some logic that you host.

         

        So you'll want the endpoint that the authorization code is delivered to be hosted by you, and once you've obtained the access token, you can set a cookie with the access token then redirect the browser back to the page on the community that the user was on (make sure to set the cookie in a domain that can be read by the community).

         

        I hope that helps. Let me know if you need any additional help with this.

         

        Thanks,

         

        -Doug