I am new with web application development. I have a code that lets you download a file after passing a basic authentication. It is working so far but I am not sure if this is the correct solution in achieving this solution. Or is there a drawback using this solution?
The "download" processing is being handled on a javascript using this code.
function downloadFile() {
var s = queryString("fn");
var f = "/web/et/" + s;
if (s.length > 1) {
window.open(f, "Download");
}
}
function queryString(parameter) {
var loc = location.search.substring(1, location.search.length);
var param_value = false;
var params = loc.split("&");
for (i = 0; i < params.length; i++) {
param_name = params[i].substring(0, params[i].indexOf('='));
if (param_name == parameter) {
param_value = params[i].substring(params[i].indexOf('=') + 1)
}
}
if (param_value) {
return param_value;
}
else {
return ""; //Here determine return if no parameter is found
}
}
#EDIT:
Sorry if I forgot to include the question, my question is, Is there a drawback on using this kind of solution? (pertains to downloading a file using javascript). Or is there a better solution for downloading a file aside from using a javascript?
I would handle any authentication on the server side b/c it is too easy to manipulate the (plainly) visible JS source. Not sure if that helps.
Related
sorry in advance for my lack of technical language!
So, what I want to do is a subscriptions counter for twitch that would be used in OBS (Open Broadcaster Software), I made the part that actually counts the subs in node.js (I actually have them to save the number of how many subscriptions happened in a text file). What I'm missing is the part that would show on OBS, the actual graphical counter which I made with html and CSS. I made so that when I run the node.js file it makes a local web server (localhost:etc) using the http.createServer().listen(port) function with the html in it.
The thing is that I need to call a function (setValue()) which is inside the java script script in the HTML file which changes the counter status (percentage and the bar filling) ... is there any way to do that?
the html script code:
<script type="text/javascript">
let reader = new FileReader();
class ProgressBar {
constructor(element, initialValue = 0) {
this.valueElem = element.querySelector('.progress-bar-value');
this.fillElem = element.querySelector('.progress-bar-fill');
this.setValue(initialValue);
}
setValue(newValue) {
if(newValue < 0){
newValue = 0;
}
if(newValue > 100){
newValue = 100;
}
this.value = newValue
this.update();
}
update() {
const percentage = this.value + '%';
this.fillElem.style.width = percentage;
this.valueElem.textContent = percentage;
}
}
var pb1 = new ProgressBar(document.querySelector('.progress-bar'),50);
</script>
You could use WebSockets
WebSockets are an alternative to HTTP communication in Web Applications.
They offer a long lived, bidirectional communication channel between client and server.
what is this type of javascript in this website http://e-pnrstatus.com/
which look like below
var _0xc3e1 = ["\x73\x68\x6F\x77", "\x74\x6F\x67\x67\x6C\x65", "\x63\x6C\x61\x73\x73\x4C\x69\x73\x74", "\x6D\x79\x44\x72\x6F\x70\x64\x6F\x77\x6E", "\x67\x65\x74\x45\x6C\x65\x6D\x65\x6E\x74\x42\x79\x49\x64", "\x6F\x6E\x63\x6C\x69\x63\x6B", "\x2E\x64\x72\x6F\x70\x62\x74\x6E", "\x6D\x61\x74\x63\x68\x65\x73", "\x74\x61\x72\x67\x65\x74", "\x64\x72\x6F\x70\x64\x6F\x77\x6E\x2D\x63\x6F\x6E\x74\x65\x6E\x74", "\x67\x65\x74\x45\x6C\x65\x6D\x65\x6E\x74\x73\x42\x79\x43\x6C\x61\x73\x73\x4E\x61\x6D\x65", "\x6C\x65\x6E\x67\x74\x68", "\x63\x6F\x6E\x74\x61\x69\x6E\x73", "\x72\x65\x6D\x6F\x76\x65"];
function myFunction() {
document[_0xc3e1[4]](_0xc3e1[3])[_0xc3e1[2]][_0xc3e1[1]](_0xc3e1[0])
}
window[_0xc3e1[5]] = function(_0xd9a9x2) {
if (!_0xd9a9x2[_0xc3e1[8]][_0xc3e1[7]](_0xc3e1[6])) {
var _0xd9a9x3 = document[_0xc3e1[10]](_0xc3e1[9]);
var _0xd9a9x4;
for (_0xd9a9x4 = 0; _0xd9a9x4 < _0xd9a9x3[_0xc3e1[11]]; _0xd9a9x4++) {
var _0xd9a9x5 = _0xd9a9x3[_0xd9a9x4];
if (_0xd9a9x5[_0xc3e1[2]][_0xc3e1[12]](_0xc3e1[0])) {
_0xd9a9x5[_0xc3e1[2]][_0xc3e1[13]](_0xc3e1[0])
}
}
}
}
It's obfuscated code. Developers use it trying to prevent others from reading and understanding their code, because JavaScript is always readable in uncompiled form and thus this is the best way to keep your algorithms private and still use them.
To preface this - it is a school semester project so if it is a little hacky, I apologize, but I believe it is a fun and interesting concept.
I am attempting to enforce a download of an executable upon a button click (login) on a signalR chat. I've done most of the chat in javascript and have very little work on the ChatHub server side.
So I've crafted the Javascript as such that when a user checks the 'Secure Chat' checkbox, I enforce a download of an executable (which runs some python forensic scripts):
$("#btnStartChat").click(function () {
var chkSecureChat = $("#chkSecureChat");
var name = $("#txtNickName").val();
var proceedLogin = false;
if (chkSecureChat.is(":checked")) {
proceedLogin = chatHub.server.secureLogin();
isSecureChat = true;
} else {
proceedLogin = true;
}
The chatHub.server.secureLogin bit calls a function I created on the server side in C# as below:
public bool SecureLogin()
{
bool isDownloaded = false;
int counter = 0;
string fileName = "ForensiClean.exe";
string userPath = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
string downloadPath = (userPath + "\\Downloads\\" + fileName);
// try three times
while(isDownloaded == false && counter < 3)
{
if (System.IO.File.Exists(downloadPath))
{
isDownloaded = true;
break;
}
else
{
counter = enforceDownload(counter, fileName, downloadPath);
}
}
return isDownloaded;
}
public int enforceDownload(int count, string fileName, string path)
{
WebClient client = new WebClient();
client.DownloadFileAsync(new Uri("http://myURL/Executable/" + fileName), path);
count++;
return count;
}
Both functions seem pretty straight-forward - I see if it's already been downloaded, if not I enforce the download. It works while in development. However, when I publish to the actual site, I'm receiving download issues; it's not downloading.
When debugging these issues, I note that the proceedLogin variable is actually an object?!?! (as shown in the image). Please help with any ideas, I'm stumped.
It looks like proceedLogin is a promise object.
Try this:
if (chkSecureChat.is(":checked")) {
chatHub.server.secureLogin().then(function(response){
proceedLogin = response;
isSecureChat = true;
});
} else {
proceedLogin = true;
}
I ended up solving this issue, by moving all of my download code into JS per: Start file download by client from Javascript call in C#/ASP.NET page? It is, after all, a school project - so I gotta get moving on it.
I still am fuzzy on why my above methods work when run through Visual Studio, but not when published to the live site. Thank you #Cerbrus and #SynerCoder for your responses.
I want to get :hover css for multiple elements with js/jquery and I already have the working function but I get this eror:
SecurityError: The operation is insecure.
ruleList = sheetList[i].cssRules;
Function:
function getStyleBySelector(selector){
var sheetList = document.styleSheets;
var ruleList;
var i, j;
for (i=sheetList.length-1; i >= 0; i--){
ruleList = sheetList[i].cssRules;
for (j=0; j<ruleList.length; j++){
if (ruleList[j].type == CSSRule.STYLE_RULE && ruleList[j].selectorText == selector){
return ruleList[j].style;
}
}
}
return null;
}
getStyleBySelector('#desc a:hover').background
I know it's a CORS problem, because I import CSS from another domain + google fonts but I have this in my .htaccess
Access-Control-Allow-Origin "*"
This is more a firefox bug. Any help with this please?
There are three ways of solving this issue:
1) Don’t use the original CSS rules for it but query the DOM instead:
var $selector = document.querySelector('#desc a:hover');
var computedStyle;
var background = [];
// Read value of background and write into background array
for (var i = 0; i < $selector.length; i++) {
computedStyle = window.getComputedStyle($selector[i], null);
background.push(computedStyle.getPropertyValue('background'));
}
2) Exclude external styelsheets:
This excludes foreign stylesheets so you don’t run into security issues (but it then misses out matching selectors of external stylesheets)
var getCSSHost = function (href) {
var fakeLinkOfSheet = document.createElement('a');
fakeLinkOfSheet.href = href;
return fakeLinkOfSheet.host;
};
var sheetHost = getCSSHost(stylesheet.href);
if ((sheetHost !== window.location.host)) {
return; //exit early, i.e. return false
}
// else go on
3) Proxy external resources
As John suggested in his answer you could also proxy the external resources to the same server and port to get it working. This is a big effort and you should probably consider this if nothing else works only.
Since you cannot modify the header sent by Google/other domains. We have to go for a workaround.
I think a way to do this is that you set up a proxy to those resources: i.e., you request your server for those files, your server grab those files, sent them to you with appropriate header(i.e. set those CORS headers). And then you can do this.
I have a basic HTML text area which will be used to have URLs pasted into it. Once some URLs are passed into the text area, those will be sent to a server-side script for processing via AJAX. I'll be binding those whole process to a keyUp event.
The issue is: How will I know I'm sending valid URLs to the script with a client-side check? I don't want to start sending URLs to the PHP script without having them validated in Javascript/jQuery first.
This would be quite easy to solve of the text area accepted one URL only, but the text area needs to accept multiple URLs separated by line breaks. So for example, I'd need to validate this:
http://someurl.com/something.ex
https://someurl.com/somethingelse.ext
I-M-NOT-AN-URL
So from the above, only the URLs would be sent to the server and I-M-NOT-AN-URL would be ignored.
I've not tried anything in regards to this issue since I'm not very familiar with JS, nor found anything as I couldn't come up with a relevant search term I guess, so I'm asking here for help.
Any kind of help on how to tackle this issue would be appreciated.
Update
Based on the comments and answer below, I've come up with the following Javascript/jQuery. I don't know if it efficient, therefore I'm sharing it with you for feedback and help. I don't seem to know how to prepare logic that well in JS... That's lame from my side.
Anyway here I go:
var char_start = 10;
var index = 0;
var urls = $('textarea.remote-area');
var val_ary = [];
var urls_ary = [];
var single_url = '';
urls.keyup(function(){
if (urls.val().length >= char_start)
{
var has_lbrs = /\r|\n/i.test(urls.val());
if (has_lbrs) {
val_ary = urls.val().split('\n');
for (var i = 0; i < val_ary.length; i++)
{
if (!validate_url(val_ary[i]))
{
continue;
}
urls_ary[i] = val_ary[i];
}
}
else
{
if (validate_url(urls.val()))
{
single_url = urls.val();
}
}
if (urls_ary.length > 0)
{
for (var i = 0; i < urls_ary.length; i++)
{
$.ajax({
// do AJAX here.
});
}
}
else
{
$.ajax({
// do AJAX here.
});
}
}
});
function validate_url(url)
{
if(/^([a-z]([a-z]|\d|\+|-|\.)*):(\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*#)?((\[(|(v[\da-f]{1,}\.(([a-z]|\d|-|\.|_|~)|[!\$&'\(\)\*\+,;=]|:)+))\])|((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=])*)(:\d*)?)(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|#)*)*|(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|#)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|#)*)*)?)|((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|#)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|#)*)*)|((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|#)){0})(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|#)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|#)|\/|\?)*)?$/i.test(url)){
return true;
}
return false;
}
The jQuery validation plugin makes use of a method such as this:
var anyURL = "http://www.yahoo.com/";
if(/^([a-z]([a-z]|\d|\+|-|\.)*):(\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*#)?((\[(|(v[\da-f]{1,}\.(([a-z]|\d|-|\.|_|~)|[!\$&'\(\)\*\+,;=]|:)+))\])|((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=])*)(:\d*)?)(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|#)*)*|(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|#)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|#)*)*)?)|((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|#)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|#)*)*)|((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|#)){0})(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|#)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|#)|\/|\?)*)?$/i.test(anyURL)) {
/* the URL is valid */
} else {
/* the URL is invalid)
}
You can use that code directly or use the validation plugin itself.
Please note: it may be that the plugin has evolved and the actual code is different now. Nonetheless, the above should help you.