XHR access to github's participation info - javascript

I am writing a simple widget that renders a canvas participation graph just like the one's on github.
It uses the data at http://github.com/[user]/[repo]/graphs/participation
The widget works great and is basically done. The only problem I have is when I try to retrieve the json data from the above link via XHR (rather than just copying and pasting into the widget as I have been), I run into the same origin access control problem.
Is there any way I can access this information at all, either via XHR or some hidden github api feature?

I believe Github supports JSONP and CORS through its API. You could also setup a server-side proxy, through which XHR requests are made to a same-origin page which then does a server-side request to Github.
To answer your question about the proxy, yes it's very simple. I had actually done this exact thing about two years ago using Python and Tornado. I realize this isn't PHP, but it reads close enough to english to give you the idea about how it works. This particular proxy was returning a raw gist.
# /proxy/gist
class GetGistHandler(BaseHandler):
def get(self, id, filename):
url = 'http://gist.github.com/raw/%s/%s' % (id, urllib.quote(filename))
resp = urlfetch.fetch(url)
self.finish(resp.content)
It can then be consumed with something along the lines of
$.ajax({
url: '/proxy/gist',
dataType: 'JSON',
data: {
id: $('#id').val(),
filename: $('#filename').val()
},
success: function(json) {
// ...
}
});

Related

How to POST an issue stub on GitHub using the GitHub API using the logged in user, without authentification keys?

Users of my web application are expected to provide bug reports as a GitHub issue, with a pregenerated title and body.
This works perfectly fine using GET for small bodies:
const title = getLastErrorTitle();
const body = getAllTheLogMessages();
window.open(`https://github.com/theuser/therepo/issues/new?title=${encodeURIComponent(title)}&body=${encodeURIComponent(body)}`);
If the user is logged in, GitHub presents the user with a new issue with the title and body already filled out, perfect. If not, GitHub prompts the user to log in and it works the next time.
However, if the body is too large, the GET request fails because the URL becomes too long.
After consulting the manual I tried doing the same with POST but I get a 404 from GitHub with the following test request (jQuery for brevity):
$.ajax({
type: "POST",
url: "https://api.github.com/repos/theuser/therepo/issues",
data: data = {title: "Test", body: "Test Body"},
});
My suspicion is, that the GitHub API was not designed with my use case in mind, but that POST always requires authentication and creates the full issue in one go, without letting the user change it beforehand like it is possible with GET.
How can I transfer the functionality of the GET method over to the POST method? I just want GitHub to present the user, that is currently logged in inside the browser, with a prefilled issue, without needing a token.
You can't. Otherwise, it would be a major CSRF exploit.
However, you can use OAuth authentication that will allow your application to use some features : https://developer.github.com/apps/building-oauth-apps/authorizing-oauth-apps/
Or simply, redirect the user to a new issue page (for exemple with a simple HTML link <a>) with some automatic content, using this pattern :
https://github.com/{theUser}/{theRepo}/issues/new?body={theContentYouWhant}&title={theTitleYouWhant}
Example : https://github.com/CristalTeam/php-api-wrapper/issues/new?body=Hi,%20this%20is%20the%20body%20you%20want&title=Hello,%20this%20is%20a%20prefill%20issue
What I would suggest here is to generate a personal_auth_token at gihub and pass this token in the headers under Authorization field.
To generate personal_auth_token, login to github.com, go to settings -> developers settings -> Personal access tokens and generate one.
Pass this token in headers under Auhtorization: token. So in your AJAX request, it could look something like this:
$.ajax({
url: *yourUrl*
...
beforeSend: function (xhr) {
xhr.setRequestHeader('Authorization', *token*));
},
});
One thing to note here is each of the developers POSTing to the repo will be requiring to generate their access token and you can't push this token on to a public Github repository because of obvious security breach. If you accidentally do so, the token is revoked immediately and you'll be required to create a new one.

How to hide serious business logic in JS file

In our recent applications we are using lots of AJAX in JS files to avoid frequent postbacks. But I'm worried about the public getting into some of our business logic by just checking the JS file. They can also alter the data being sent to the server using firebug or such features. So how can we avoid this scenario and protect our code from being easily visible to the world.
In this case, the public can see the server side function, parameters etc easily. So how can we avoid this headache to some extent.
var param = { id: id };
var param = JSON.stringify(param);
$.ajax({
type: "POST",
url: "qmaker.aspx/deleteQuestion",
data: param,
contentType: "application/json; charset=utf-8",
dataType: "json",
global: false,
beforeSend: function () {
$.blockUI({
message: '<h3>Deleting Question..<br><small>Please wait for a moment...</small></h3>'
});
},
success: function (data) {
if (data.d == 1) {
var n = noty( type: 'success', text: 'Question Deleted successfully.', /* ... */)
var oTable = $('#table_question).DataTable();
var row = oTable.row($(that).parents('tr:first'));
/* ... */
You don't get to pick what the client sends you. I can submit forms without even reading your HTML.
You also don't get to pick what, out of what you send to the client, the client may or may not read. You sent me a JS file, it's out of your hands now.
In traditional programs, you'd be able to relatively safely sell programs by compiling them, because the original source code was unrecoverableto some definitions of unrecoverable.
With JavaScript, you send your code to the browser, and ask them nicely to execute it. You can't expect the browser not to read all of the code, right? So why can you expect the same of the user, who is using the browser to view your page?
Make sure you application is secure and airtight even if details about your business logic are leaked. A good security stands strong even if everything about the system is known to an attacker, including the source code and the database structure.
Then again
You don't need to expose the inner workings of the server to JavaScript. The "code" you posed doesn't really reveal anything in terms of how the server works, all I know is that there's a page on qmaker.aspx that supports the deleteQuestion path, and when I hit that, with an ID, that question will be deleted. It's now up to you to think what an attacker might do with this information, and seal any attack vectors.
If you want to make it safe you should implement authentication and tokenized requests. This way it doesn't matter if the public see the requests, they will not be able to make successful requests without being authenticated and having a valid token.
Edit below: to provide some extra information.
Surely in your applications you implement some kind of login so users are authenticated and allowed (or forbidden) to use certain parts of your application.
When a user logs in, you could generate a (temporary) token on the server side, store it and pass it back to the user through browser session or similar. Then pass the token as a parameter to the ajax calls.
$ajax(url, {
data: {
token: session.token,
action: 'delete',
id: entryID
}
}
The server will check if the token has been passed and it's valid against the db records. If it is it will just perform the requested operation and return a reply, or it could just return a 401 (unauthorized) error..
If you want something more advanced and perhaps safer, you could search for oauth 2.0 authentication.

Html cloud storage?

I'm trying to make an app using phonegap, but what I want to know is if it is possible to store information online. For example, say there is a number variable, and it is added to when a button is pushed. Could that value be saved somewhere and then a totally different device can retrieve the variable?
I looked at databases, but I couldn't really understand it. I want something that can be accessed by any device as long as It has a key or something.
Is this possible? If so, how would I do it?
PhoneGap uses JS so you cannot connect to the database directly. You should create a Web service using server side languages like PHP on external server and make ajax request on your web service. This approach is possible using PhoneGap.
Sample Code will look somewhere near:
function FetchData() {
$.ajax({
async: false,
type: "GET",
url: "Your_WebService_URL",
dataType: "json",
success: function(data) {
$.each(data, function(i, object) {
if(i==="title"){
document.getElementById("title").InnerHTML = object;
}
if(i==="home_image"){
document.getElementById("title").InnerHTML = '<img src="'+object+'"/>';
}
});
},
error: function() {
alert("There was an error loading the feed");
}
});
The web service, in this case json will throw the variables. May me somewhere like this :
[{"title":"my application"},{"home_image":"http://link.com/image.png"}]
I think this article is useful to you: Loading external data into a PhoneGap app using the jQuery JSONP plugin for cross-domain access. Also see this similar question here:
This is entirely possible.
You essentially need two components: the client interface, and the server.
The client displays the results to the users, and, using your example, waits for a button to be pushed. On the push of that button, the client would send a request to the server to increment the stored value (possibly through a jQuery.post, or get, function call).
The server page, written in php for example, receives this request, and accesses a file, or more realistically a database, to increment the value.
With some Googling, this should be very doable, but post specific questions if you get stuck.

How do I get the steam API to work?

Let me start off with saying I just figured out how to use JQuery's "$.ajax()" just a few days ago. I've been able to read local .xml and .json files.
Also, I've figured out how to use the google maps API to import dynamic and static maps. (just following the google documentation)
Now, I had an idea to use steam IDs for a school project, but I keep getting this error:
XMLHttpRequest cannot load http://api.steampowered.com/ISteamUser/GetFriendList/v0001/?key=[MY_SECRET_KEY]2&steamid=76561197960435530&relationship=friend. Origin http://local.mysite.com is not allowed by Access-Control-Allow-Origin.
(I took out the key, and the generated key is suppose to allow access to http://local.mysite.com)
Here is my code:
<script type="text/javascript">
$.ajax({
url: "http://api.steampowered.com/ISteamUser/GetFriendList/v0001/?key=[MY_SECRET_KEY]&steamid=76561197960435530&relationship=friend",
dataType: "json",
success: function(data){
console.log(data);
},
error: function(req,text,error){
console.log(text);
console.log(error);
console.log("DIDN'T WORK!")
}
});
</script>
Does anybody know what's going on? I can't seem to get this to work.
See this answer and the posts here. For more background visit mdn.
Essentially you're running into a security issue where the browser won't allow you to make a request from http://local.mysite.com to http://api.steampowered.com.
Do you have access to a server? Instead of making a request like this: browser -> steampowered you can make a request like this browser -> your server -> steampowered.
You're going to want to create an endpoint on your server (so that it's in your domain) that you can send a request to, that will in turn send a request to steam powered.
What language / framework are you running and we can give you example code.

Whois with JavaScript

I want to be able to get whois data (and idn domains too) by client-side javascript. Is it possible? Maybe some free REST-like WhoIs service exists?
Try using http://whoisxmlapi.com service.
The service URL: http://www.whoisxmlapi.com/whoisserver/WhoisService
You need to specify outputFormat=json and domainName=insert_domain_here parameters..
Example URL: http://www.whoisxmlapi.com/whoisserver/WhoisService?outputFormat=json&domainName=stackoverflow.com.
Example code (using jQuery to simplify AJAX communication):
$.ajax({
url: 'http://www.whoisxmlapi.com/whoisserver/WhoisService',
dataType: 'jsonp',
data: {
domainName: 'stackoverflow.com',
outputFormat: 'json'
},
success: function(data) {
console.log(data.WhoisRecord);
}
});
HERE is the working code.
Update:
The service mentioned above is not free, but there are several free whois services that are providing HTML output and by using YQL you can retrieve the HTML as a JS. See THIS answer for more details.
Example (using jQuery & jquery.xdomainajax):
var domain = 'stackoverflow.com';
$.ajax({
url: 'http://whois.webhosting.info/' + domain,
type: 'GET',
success: function(res) {
// using jQuery to find table with class "body_text" and appending it to a page
$(res.responseText).find('table.body_text').appendTo('body');
}
});
HERE is the working code.
You need to have a look at the structure of the HTML document and select, process and display the data you are interested in. The example is just printing whole table without any processing.
What you can do if you have exec() enabled in php is create a php file with the following:
exec('whois domain.com');
and then create aa .ajax() request to the php script where you pass the domain name and output it.
An npm package called node-whois did the job for me. It's server side JS, not client side, but perhaps this will help someone.
i'm also trying to find out a free whois provider with JSON output, couldn't find one. But, there are WHOIS windows client provided by Microsoft and like someone mentioned above, we can use PHP/cgi to get the details.
I'm not sure whether there's any WHOIS lookup/query provider gives JSON output at free cost.
BTW, i just found this phpWhois from sourceforge.net, would be a good starting point to use whois from the server. This is the library used by RoboWhois / RubyWhois provider as well.
You could use whois npm module
https://www.npmjs.com/package/whois
Also in mac terminal, try this to see whois data
whois google.com

Categories