createNewDiscussion/createNewDiscussionReply via JSOM in SharePoint Discussion Board from external Angular SPA - sharepoint

Scenario:
I have an Angular SPA and a SharePoint 2013, installed in separated servers. I would like to consume a SharePoint discussion board in my SPA, means I would like to use my customized UI to perform CRU(D) operations on the SharePoint discussion board.
Through some workarounds I already achieved this objective using the SP REST API, but unfortunately since REST API doesn't allow setting some parameters for the discussion board (in particular the ParentID) I am not really able to use REST API in a satisfactory way.
In order to make it possible to work through the REST API I had to change the configuration in the IIS of the SharePoint Server to rewrite the headers and allow the Cross-Domains Call. Moreover I pass as options in the http call the digest from the context info. As I said, the comunication works, I can create new discussions or replies, but these are malformed because the API itself doesn't offer the methods that I need, but just some workaround to post not-so-good-looking messages in the discussion board (for example the threading is completely lost).
With JSOM I am doing this (I simpliefied a bit):
createReply() {
let clientContext = new SP.ClientContext("otherserver.sharepoint.com");
    let list = clientContext.get_web().get_lists().getByTitle("myDiscussionBoardName");
    let discussionItem = list.getItemById(parentTopicId); //eg. parentTopicId === 10
    let properties = {'Body': 'My Message'};
    let messageItem = SP.Utilities.Utility.createNewDiscussionReply(clientContext, discussionItem);
    for (var propName in properties) {
messageItem.set_item(propName, properties[propName])
    }
messageItem.update();
    clientContext.executeQueryAsync(() => 
{ console.log("Gotcha!", messageItem); },
  (error: any) => { console.log('Request failed', error); });
  }
But unfortunately I get a 401 error. My understanding would also be that I won't need to provide a digest, since JSOM should take care of it by itself, but I am not sure of this, nor I am aware of how I could provide the digest within a JSOM call.
Honestly this message is my last hope to get to the bottom of this. I actually am already planning to use different solutions, but I can't believe that a solution doesn't exist, in particular because using a local proxy (sp-rest-proxy, you may know it well if you develop angular application based on SP) the connection somehow works correctly.

check the below link and also I just put one the example from our code
http://sharepointsanjay.blogspot.com/2016/05/how-to-refresh-request-digest-token.html
var headers = {
"Accept": "application/json; odata=verbose",
"Content-Type": "application/json; odata=verbose",
"X-RequestDigest": document.getElementById("__REQUESTDIGEST").value,
"X-HTTP-Method": "MERGE",
"If-Match": "*"
};
return $http({
headers: headers,
method: "POST",
url: url,
data: JSON.stringify(data)
}).then(complete, failed);

Related

Confused about the Authorization Code Grant

I am attempting to do implement an authorization code grant I start by calling (from the browser):
https://account-d.docusign.com/oauth/auth?response_type=code&scope=signature&client_id=1ee7dba4-ca87-4451-8b82-a5df0d95fa41&state=a39fh23hnf23&redirect_uri=http://localhost:4000/docusign/authGrantReturn/
Sometimes I am asked for login/password, which always tells me that the response type is not supported or that the user/pass are not valid. I found this previous answer (Authorization Code Grant error: invalid authentication request) but did not find the checkbox discussed.
Otherwise, it calls back my rediect url (handled in node), and provides me with a 'code' and returns the 'state' I previously sent, and here begins my confusion:
I make an http request using the fetch library like so:
let combination = `${integrationKey}:${secretKey}`;
let b64Combination = Buffer.from(combination).toString('base64');
fetch('https://account-d.docusign.com/oauth/token?grant_type:authorization_code&code='+b64Combination,{
method: 'GET',
headers: { 'Authorization': 'Basic ${b64Combination}', 'Content-Type': 'application/x-www-form-urlencoded', 'Content-Encoding': 'gzip'}
})
.then...
But this returns html content in the body.
Does that mean I should make the call to https://account-d.docusign.com/oauth/token from the browser rather than node?
When it asks me to log in, am I to use my sand-box account credentials? or the credentials of a regular docusign user?
Sorry for the confused question...
Best regards,
Adrian.
I would suggest you use the DocuSign nodeJS SDK and code example.
https://github.com/docusign/eg-03-node-auth-code-grant
Follow the instructions here, this code makes it very simple and if you update all your info - it just works.
Then, you can see how to modify it to your needs.
(for your second question, yes, for now you use your sandbox creds when you build/test your app)

Excel Task Pane add-in to show content from external source

I am trying to build an Excel/Word task pane add-in that should show content from our site. The content/data is passed in XML format.
What I have tried to do is the following:
Office.initialize = function (reason) {
$(document).ready(function () {
app.initialize();
$.support.cors = true;
var data = '';
$.ajax({
type: "GET",
contentType: "application/json; charset=utf-8",
url: 'http://addons.mysite.com/excel-taskpane-data.php',
data: data,
dataType: "json",
success: onQuerySuccess,
error: onQueryError
});
function onQuerySuccess(res, statusText) {
console.log('success!!' + res.statusText);
}
function onQueryError(res, statusText){
console.log('failed!!' + res.statusText);
}
});
};
As you can understand from the code above I was just checking if connection could be made to the external source, but I am getting "Access Denied" in the console.
I am not really sure how should I request data from an external source and whether it is possible at all?
Please help
You mentioned 'external' so I bet http://addons.mysite.com/ is not the domain that serves your web add-in.
To make it work you have to check several things.
Serving with Https. As written by Michael make sure you use https. Mixed content (mixing of http and https) is blocked by most server and Office web add-ins can only be served with https.
Make sur your PHP web api supports CORS.
I am no PHP expert so here is a small link
Try to specify https://addons.mysite.com as AppDomain
The sandboxed iFrame allow only request and navigation on the same domain (the one that you use to serve you web-addin). But you can specify some exceptions see here. It works with navigation and I am not sure it works with XHR...
If step 3 did not work try to use JSON/P techniques as described here
JSON/P with Office add-ins
Yes, you can make Ajax HTTP requests from Office web add-ins such as your Excel/Word task pane. They work exactly the same as they would on a normal web page, except we have an additional requirement of using "https" rather than "http" to access the endpoint.
I can't identify the cause of your specific issue without information about the actual endpoint you're calling. Start by just trying your code on a normal web page and access it normally with a web browser. Once you have that working, then point an add-in to the page. That should fix your issue, but if you still have a problem where the exact same code is working in a normal browser and failing in an add-in, let us know.

403 when trying to list web spaces via Azure websites management REST API

I'm just in the process of experimenting with the Azure rest api's in preparation for some work I'm heading into...
Within node.js I'm trying to obtain a list of webspaces hosted by my subscription using the following code...
var websiteOptions = {
hostname: 'management.core.windows.net',
path: '/<<Subscription-ID>>/services/webspaces',
method: 'GET',
pfx: new Buffer(managementCert, 'base64'),
strictSSL: true,
headers: {
'x-ms-version': '2013-06-01'
}
};
websiteOptions.agent = new https.Agent(websiteOptions);
var request = https.request(websiteOptions,function(res){
console.log('Status Code:', res.statusCode);
console.log('Headers:', res.headers);
When executed it returns back with..
<Error xmlns="http://schemas.microsoft.com/windowsazure"
xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<Code>AuthenticationFailed</Code>
<Message>The server failed to authenticate the request. Verify that the certificate is valid and is associated with this subscription.
</Message>
</Error>
The strange thing is that if I replace ..
/<<subscription-ID>>/services/webspaces
with...
/<<subscription-ID>>/services/hostedservices
That specific call works like a charm, returning a list of hosted services - so this leads me to believe that I'm encoding/attaching my management certificate correctly.
I have tried various api versions in the headers without much luck, I have also read various sections of this article without much luck.
So why are my credentials working in one section of the API and not the websties section
What am I missing, I'm sure it's something really simple :|
OK so now I feel daft, and it just goes to show that even big companies can get it wrong..
I have been playing a bit more and decided to drop a forward slash onto the end of the API call for the web spaces endpoint.. and...
Bingo... it worked like a treat!!!
Would have been nice if Microsoft was consistent across it's API endpoints, the hosted services end point for instance didn't need this trailing slash.
Also, accurate error messages would have been nice too, instead of just reporting an invalid credentials exception!!!
As always.. the simple things in life :(

Updating a wiki page with the REST API

How do you update a SharePoint 2013 wiki page using the REST API?
Three permutations:
Reading an existing page (content only)
Updating an existing page
Creating a new page
For reading an existing page, of course I can just to a "GET" of the correct URL, but this also brings down all the various decorations around the actual data on the wiki page-- rather than fish that out myself, it would be better if there was a way to just get the content if that is possible.
Are there special endpoints is the REST API that allow for any of these three operations on wiki pages?
As stated in GMasucci's post, there does not appear to be a clean or obvious way of instantiating pages through the REST API.
You can call the AddWikiPage method from the SOAP service at http://[site]/_vti_bin/Lists.asmx. This is an out of the box service that will be accessible unless it has been specifically locked down for whatever reason.
To read the content of a wiki page through the REST API, you can use the following endpoint:
https://[siteurl]/_vti_bin/client.svc/Web/GetFileByServerRelativeUrl('/page/to/wikipage.aspx')/ListItemAllFields
The content is contained within the WikiContent field. You may want to add a select to that URL and return it as JSON to reduce the amount of data getting passed over if that is a concern.
As for updating the content of an existing wiki page, it is not something I have tried but I would imagine it's just like populating another field through the REST API. This is how I would expect to do it:
Do a HTTP POST to the same endpoint as above
Use the following HTTP headers:
Cookie = "yourauthcookie"
Content-Type = "application/json;odata=verbose"
X-RequestDigest = "yourformdigest"
X-HTTP-Method, "MERGE"
If-Match = "etag value from entry node, returned from a GET to the above endpoint"
Post the following JSON body
{
"__metadata": { "type": "SP.Data.SitePagesItem" },
"WikiField" : "HTML entity coded wiki content goes here"
}
The interim answer I have found is to not utilise REST, as it appears to not be
fully documented
fully featured
supported across Sharepoint 2013 and On-line in the same way
So my current recommendation would be to utilise the SOAP services to achieve the same, as these are more documented and easily accessible.

Jquery ajax.post() ie security issue

i got simple jQuery ajax post request
$.ajax({
url: "/_layouts/TK_Editor/DemoHandler.ashx", //
contentType: "application/json; charset=utf-8", //cherset set
type: 'POST', //
dataType: "json", //
data: JSON.stringify(json_str), //
success: OnComplete, //function
error: OnFail //function
});
I browsed dozens of similar problemms here and google, but most of them are about crossdomain or character set, well i got no crossdomain, no anything complicated.
works just fine in ffox, chrome, even opera...
after json_str parsed by DemoHandler, web service execs some TSQL procedures, but when i try to make ajax request from IE (8+), my service doesn't exec any procedures and i got endless waiting till request fires.
However, when i disable most all of security in IE, it suddenly works!
Can anyone explain me why this happens and what exact option in security doesn't allow jQuery.ajax request to fire well, and if it is possible - how to avoid this scenario?
p.s: webservice works just fine too, described in here
Once again i answered my own question, anyway.
https://github.com/jaubourg/ajaxHooks/blob/master/src/xdr.js
here's workaround with some limitations to make things go right.
Complete description located here (if anyone wants to read more)
http://bugs.jquery.com/ticket/8283
most important last record in ticket.
Cheers!

Resources