Alfresco - submitting dynamic forms to upload.post with javascript - alfresco

I'm encountering issues with a dashlet that I'm trying to develop for Alfresco. It's a simple drag and drop file upload dashlet using HTML 5's drag and drop and file APIs. For the drop event listener, I call the following function which is seemingly the cause of all the problems:
function handleFileSelect(evt) {
var files = evt.target.files || evt.dataTransfer.files,
tmpForm, tmpDest, tmpMeta, tmpType, tmpName, tmpData;
dropZone.className = "can-drop";
evt.stopPropagation();
evt.preventDefault();
for (var i=0,f;f=files[i];i++) {
tmpForm = document.createElement('form');
tmpDest = document.createElement('input');
tmpDest.setAttribute('type', 'text');
tmpDest.setAttribute('name', 'destination');
tmpDest.setAttribute('value', destination);
tmpForm.appendChild(tmpDest);
tmpMeta = document.createElement('input');
tmpMeta.setAttribute('type', 'text');
tmpMeta.setAttribute('name', 'mandatoryMetadata');
tmpMeta.setAttribute('value', window.metadataButton.value);
tmpForm.appendChild(tmpMeta);
tmpType = document.createElement('input');
tmpType.setAttribute('type', 'text');
tmpType.setAttribute('name', 'contenttype');
tmpType.setAttribute('value', "my:document");
tmpForm.appendChild(tmpType);
tmpName = document.createElement('input');
tmpName.setAttribute('type', 'text');
tmpName.setAttribute('name', 'filename');
tmpName.setAttribute('value', f.name);
tmpForm.appendChild(tmpName);
tmpData = document.createElement('input');
tmpData.setAttribute('type', 'file');
tmpData.setAttribute('name', 'filedata');
tmpData.setAttribute('value', f);
tmpForm.appendChild(tmpData);
Alfresco.util.Ajax.request({
url: Alfresco.constants.PROXY_URI_RELATIVE + "api/upload",
method: 'POST',
dataForm: tmpForm,
successCallback: {
fn: function(response) {
console.log("SUCCESS!!");
console.dir(response);
},
scope: this
},
failureCallback: {
fn: function(response) {
console.log("FAILED!!");
console.dir(response);
},
scope: this
}
});
}
}
The server responds with a 500, and if I turn on debug level logging for web scripts, upload.post returns with:
DEBUG [repo.jscript.ScriptLogger] ReferenceError: "formdata" is not defined.
Which, to me at least, indicates that the form above isn't getting submitted properly (if at all). When digging through it all with Chrome dev tools, I notice that that request payload looks drastically different from something such as a REST client. The above code results in the request using Content-Type: application/x-www-form-urlencoded whereas using a REST client, or Alfresco Share's standard uploader(s) are using Content-Type: multipart/form-data. If I need to submit the form using multipart/form-data, what is the easiest way to write out the request body (with the boundaries, Content-Disposition's, etc...) to include the file being uploaded?

I ditched the idea of creating a form HTML Element through javascript, and assume that if a browser supports the File API, and the Drag and Drop API, that they will likely also support the XMLHttpRequest2 API. As per HTML5 File Upload to Java Servlet, The above code now reads:
function handleFileSelect(evt) {
var files = evt.target.files || evt.dataTransfer.files,
xhr = new XMLHttpRequest();
dropZone.className = "can-drop";
evt.stopPropagation();
evt.preventDefault();
for (var i=0,f;f=files[i];i++) {
formData = new FormData();
formData.append('destination', destination);
formData.append('mandatoryMetadata', window.metadataButton.value);
formData.append('contenttype', "my:document");
formData.append('filename', f.name);
formData.append('filedata', f);
formData.append('overwrite', false);
xhr.open("POST", Alfresco.constants.PROXY_URI_RELATIVE + "api/upload");
xhr.send(formData);
}
}
with the necessary event listeners to be added later. It would seem that the Alfresco AJAX methods that come stock and standard heavily modify the underlying requests being made, making it very difficult for one to simply send a FormData() object.

Related

Is there a way to add a post in wordpress via googlescript?

I have a form in googlescript where I can add a user to a sheet.
Is there a way to implement some lines in that code so the script adds a post on a wordpress page?
I read that it's possible via wp_insert_post , but I have no idea how that works in my case.
EDIT:
As Spencer suggested I tried to do it via WP REST API.
The following code seems to be working .............
function httpPostTemplate() {
// URL for target web API
var url = 'http://example.de/wp-json/wp/v2/posts';
// For POST method, API parameters will be sent in the
// HTTP message payload.
// Start with an object containing name / value tuples.
var apiParams = {
// Relevant parameters would go here
'param1' : 'value1',
'param2' : 'value2' // etc.
};
// All 'application/json' content goes as a JSON string.
var payload = JSON.stringify(apiParams);
// Construct `fetch` params object
var params = {
'method': 'POST',
'contentType': 'application/json',
'payload': payload,
'muteHttpExceptions' : true
};
var response = UrlFetchApp.fetch(url, params)
// Check return code embedded in response.
var rc = response.getResponseCode();
var responseText = response.getContentText();
if (rc !== 200) {
// Log HTTP Error
Logger.log("Response (%s) %s",
rc,
responseText );
// Could throw an exception yourself, if appropriate
}
else {
// Successful POST, handle response normally
Logger.log( responseText );
}
}
But I get the error:
[16-09-28 21:24:29:475 CEST] Response (401.0)
{"code":"rest_cannot_create","message":"Sorry, you are not allowed to
create new posts.","data":{"status":401}}
Means: I have to authenticate first.
I installed the plugin: WP REST API - OAuth 1.0a Server
I setup a new user and got a client key and client user.
But from here I have no clue what to do : /
It is possible. Wordpress has a REST API. I can be found at:
http://v2.wp-api.org/
You will use the UrlFetchApp Service to access this api. Documentation can be found at:
https://developers.google.com/apps-script/reference/url-fetch/url-fetch-app
Read the docs and try to write some code. It you get stuck post the code that is confusing you here and I'll update this answer.
You should add you authentification in the header :
var headers = {
... ,
'Authorization' : 'Basic ' + Utilities.base64Encode('USERNAME:PASSWORD'),
};
And then add your header in your parameters :
var params = {
'method': 'POST',
'headers': headers,
'payload': JSON.stringify(payload),
'muteHttpExceptions': true
}
And then use UrlfetchApp.fetch
var response = UrlFetchApp.fetch("https://.../wp-json/wp/v2/posts/", params)
Logger.log(response);
You need to pass the basic auth, like this:
// Construct `fetch` params object
var params = {
'method': 'POST',
'contentType': 'application/json',
'payload': payload,
'muteHttpExceptions' : true,
"headers" : {
"Authorization" : "Basic " + Utilities.base64Encode(username + ":" + password)+"",
"cache-control": "no-cache"
}
};
thank you for giving me these important links.
<3
I installed WP REST API and the OAuth plugin.
In the documentation is written:
Once you have WP API and the OAuth server plugins activated on your
server, you’ll need to create a “client”. This is an identifier for
the application, and includes a “key” and “secret”, both needed to
link to your site.
I couldn't find out how to setup a client?
In my GoogleScriptCode according to the WP API I get the error:
{"code":"rest_cannot_create","message":"Sorry, you are not allowed to create new posts.","data":{"status":401}}
Edit: I found it - it's under User/Application
I'll try to figure it out and get back to you later.

Load a webpage that requires basic authentication in a Windows 8 App

How would you load an external site that requires basic authentication inside an iframe in a Windows 8 HTML/JavaScript app?
I've found that you can't use URLs of the form http://username:password#host/.
In order to load the URL I was trying to load, I had to use a webview or x-ms-webview and invoke it's navigateWithHttpRequestMessage function in order to pass the basic authentication header.
This resulted in the following code structure:
function ready(element, options) {
var webview = document.querySelector('[data-hook~="camera"]');
webview.navigateWithHttpRequestMessage(buildRequest());
}
function buildRequest() {
var username = 'username',
password = 'password',
Crypto = Windows.Security.Cryptography,
Http = Windows.Web.Http,
request,
buffer,
token;
request = new Http.HttpRequestMessage(
Http.HttpMethod.get,
new Windows.Foundation.Uri('http://ipcamera/'));
buffer = Crypto.CryptographicBuffer.convertStringToBinary(
[username, password].join(':'),
Crypto.BinaryStringEncoding.utf8);
token = Crypto.CryptographicBuffer.encodeToBase64String(buffer);
request.headers.authorization = new Http.Headers.HttpCredentialsHeaderValue('basic', token);
return request;
}
The caveat to this is that none of the DOM ready events seem to fire, so if you need to interact with the external site, you'll have to play with timers.

HTTP requests in Intel XDK

I previously built an app in the Intel XDK platform pre the Feb 23rd update and now the software has updated when i try to run the emulator it just crashes.
previously i sent a get request to a process php page for a login in the following way.
$(document).ready(function(){
$('form.login').submit(function () {
var user = $(this).find("[name='user']").val();
var pass = $(this).find("[name='pass']").val();
var sublogin = $(this).find("[name='sublogin']").val();
// ...
$.ajax({
type: "POST",
url: "http://www.domain.com/data/apps/project1/process.php",
data: {
user : user,
pass : pass,
sublogin : sublogin,
},
success: function(response){
if(response == "1")
{
$("#responsecontainer").html(response);
window.location.href = "menu.html";
}
// Login failed
else
{
$("#responsecontainer").html(response);
}
//alert(response);
}
});
this.reset();
return false;
});
});
However it seems that this is the piece of code that is causing the problems, if I remove this item of code the project no longer crashes.
When i read through the Intel XDK documents it only shows HTTP request to call XML files.
So i was hoping that somebody may know why this is causing the problem or how i might construct it so that Intel XDK doesn't crash.
There is a regression bug with regards to relative location URL referenced through emulator, a fix is being worked on. This is related to emulator only. Your app should work fine with test tab using App Preview on the device and using the build.
Till we come up with a fix for emulator crash, here is a workaround. The issue arises when you are trying to change the location of your current page with window.location.href = "menu.html"; and emulator is not able to resolve the relative path during ajax call.
Please use the following code as a workaround.
var newLocation = 'menu.html';
if ( window.tinyHippos ) {
// special case for emulator
newLocation = getWebRoot() + newLocation;
}
document.location.href=newLocation;
function getWebRoot() {
"use strict" ;
var path = window.location.href ;
path = path.substring( 0, path.lastIndexOf('/') ) ;
path += '/';
return path;
}
Swati

How to fetch a wordpress admin page using google apps script?

I need to fetch a page inside my Wordpress blog admin area. The following script:
function fetchAdminPage() {
var url = "http://www.mydomain.invalid/wp/wp-admin/wp-login.php";
var options = {
"method": "post",
"payload": {
"log": "admin",
"pwd": "password",
"wp-submit": "Login",
"redirect_to":"http://www.mydomain.invalid/wp/wp-admin/edit-comments.php",
"testcookie": 1
}
};
var response = UrlFetchApp.fetch(url, options);
...
}
is executed without errors. Anyway, response.getContentText() returns the login page, and I am not able to access the page http://www.mydomain.invalid/wp/wp-admin/edit-comments.php which is the one I want to fetch.
Any idea on how to do this?
There might be an issue with Google Apps Scripts and post-ing to a URL that gives you back a redirection header.
It seems like it might not be possible to follow the redirect with a post - here's a discussion on the issue -
https://issuetracker.google.com/issues/36754794
Would it be possible, if you modify your code to not follow redirects, capture the cookies and then do a second request to your page? I haven't actually used GAS, but here's my best guess from reading the documentation:
function fetchAdminPage() {
var url = "http://www.mydomain.invalid/wp/wp-admin/wp-login.php";
var options = {
"method": "post",
"payload": {
"log": "admin",
"pwd": "password",
"wp-submit": "Login",
"testcookie": 1
},
"followRedirects": false
};
var response = UrlFetchApp.fetch(url, options);
if ( response.getResponseCode() == 200 ) {
// Incorrect user/pass combo
} else if ( response.getResponseCode() == 302 ) {
// Logged-in
var headers = response.getAllHeaders();
if ( typeof headers['Set-Cookie'] !== 'undefined' ) {
// Make sure that we are working with an array of cookies
var cookies = typeof headers['Set-Cookie'] == 'string' ? [ headers['Set-Cookie'] ] : headers['Set-Cookie'];
for (var i = 0; i < cookies.length; i++) {
// We only need the cookie's value - it might have path, expiry time, etc here
cookies[i] = cookies[i].split( ';' )[0];
};
url = "http://www.mydomain.invalid/wp/wp-admin/edit-comments.php";
options = {
"method": "get",
// Set the cookies so that we appear logged-in
"headers": {
"Cookie": cookies.join(';')
}
};
response = UrlFetchApp.fetch(url, options);
};
};
...
}
You would obviously need to add some debugging and error handling, but it should get you through.
What happens here is that we first post to the log-in form. Assuming that everything goes correctly, that should give us back a response code of 302(Found). If that's the case, we will then process the headers and look specifically for the "Set-Cookie" header. If it's set, we'll get rid of the un-needed stuff and store the cookies values.
Finally we make a new get request to the desired page on the admin( in this case /wp/wp-admin/edit-comments.php ), but this time we attach the "Cookie" header which contains all of the cookies acquired in the previous step.
If everything works as expected, you should get your admin page :)
I would advise on storing the cookies information(in case you're going to make multiple requests to your page) in order to save time, resources and requests.
Again - I haven't actually tested the code, but in theory it should work. Please test it and come back to me with any findings you make.

how to access a file from target URL after an XMLHttpRequest post

I am trying to upload and save an image file to a server using an XMLHttpRequest POST after allowing file selection to be done on the client's side using HTML5 and java script (using an html input element).
My problem is that cannot find out how to actually get a hold of the file from the server side and save it to the server.
This is my code:
xhr = new XMLHttpRequest();
// Update progress bar etc
xhr.upload.addEventListener("progress", function(evt) {
if (evt.lengthComputable) {
progressBar.style.width = (evt.loaded / evt.total) * 100 + "%";
}
else {
// No data to calculate on
}
}, false);
// File uploaded
xhr.addEventListener("load", function() {
progressBarContainer.className += " uploaded";
progressBar.innerHTML = "Uploaded!";
}, false);
xhr.open("post", "imageSave.aspx", true);
// Set appropriate headers
xhr.setRequestHeader("Content-Type", "multipart/form-data");
xhr.setRequestHeader("X-File-Name", file.fileName);
xhr.setRequestHeader("X-File-Size", file.fileSize);
xhr.setRequestHeader("X-File-Type", file.type);
// Send the file
xhr.send(file);
You can retrieve the file using Request.InputStream but that won't work unless there is no other data in your XHR entry.

Resources