Trying to create a firefox addon that accesses the browser cookies. Following googled tutorials I've written the following function but looks like the Services.jsm is not accessible?
Components.utils.import("resource://gre/modules/Services.jsm");
var myExtension = {
myListener: function(evt) {
//I get here
alert("Received from web page: " +
evt.target.getAttribute("attribute1") + "/" +
evt.target.getAttribute("attribute2"));
//I dont see anything dumped
let enum = Services.cookies.getCookiesFromHost("example.com");
while (enum.hasMoreElements()) {
var cookie = e.getNext().QueryInterface(Ci.nsICookie2);
dump(cookie.host + ";" + cookie.name + "=" + cookie.value + "\n");
}
}
}
document.addEventListener("MyExtensionEvent", function(e) { myExtension.myListener(e); }, false, true);
Thanks #Shakur I didn't catch that e and yep you're right it needs to be fixed to enum.
I'm not familiar with cookie service, I would have to read up on it but you're on right track.
This is because you have not defined Ci you use Ci in the while loop. You can replace Ci with Components.interfaces and it should fix it up. :) If you want to use the C* short forms it is typically done by adding to the top: const {Cc:classes, Cu:utils, Ci:interfaces, Cr:results, CC: Constructor} = Components as seen in this example here: https://codereview.stackexchange.com/questions/56821/improvements-to-nsizipreader-and-nsiscriptableinputstream/56824#56824
Related
I am trying to push weather data into Google Analytics. (I am following a tutorial online; I am not proficient in Javascript but I know Python.) I have set up datalayer variables, tags and triggers, but I have a custom HTML tag that calls Openweathermap API, and pushes all this data to the datalayer, so my tag can then take this information and fire back to Google Analytics.
Could someone please have a look at this code and tell me why I get a "Unexpected Token on Line 28 ({)" error?
<script>
(function() {
var fetchWeatherData = function(longitude, latitude) {
// Open Weather Map
var owmAppKey = '<baeb0853a54bef1870ecdd0345bb0f5e>';
jQuery.getJSON('https://api.openweathermap.org/data/2.5/weather?lat=' + latitude + '&lon=' + longitude + '&units=metric&APPID=' + owmAppKey)
.done(function(data) {
window.dataLayer.push({
event: 'weatherDone',
weather: data.weather[0].main,
temperature: data.main.temp.toFixed(0) + ' °C'
});
}).fail(function(jq, status, msg) {
console.log('Weather request failed: ' + status + ' - ' + msg);
});
};
var geoLocateUser = function() {
$.getJSON('//extreme-ip-lookup.com/json/')
.done(function(data) {
fetchWeatherData(data.lon, data.lat);
}).fail(function(status, msg) {
console.log('IP request failed: ' + status + ' - ' + msg);
});
};
if (typeof {{Session alive}} === 'undefined') {
geoLocateUser();
}
// Reset "session" cookie with a 30-minute expiration
var d = new Date();
d.setTime(d.getTime()+1800000);
var expires = "expires="+d.toGMTString();
document.cookie = "session=1; "+expires+"; path=/";
})();
</script>
I am guessing this is a really basic Syntax error that is easy to fix, but I am not proficient with Javascript and cannot figure this out.
Many thanks!
A few things:
You're getting an error because typeof {{...}} is improper syntax.
Also, Session alive isn't anything. If it's a variable it should be one word like Session_alive or Session-alive or sessionAlive.
Also, double curly braces {{...}}(moustache template) are usually used in some JS frameworks but are not a feature of vanilla JS.
Single curly braces indicate an object (ex: {a: 'one', b: 'two'}.
If sessionAlive was a variable of some kind and you wished to verify if it was an object you'd write typeof sessionAlive.
But if you're checking to see if the value Session is alive then you'd write a conditional such as if (Session === 'alive') ...,
or check if Session is undefined such as if (Session === undefined) ...
Can you check the "Session alive" tag is properly set up in Google Tag Manager?
var val = 3;
var code = "var a = 5; if (a >= val) { console.log(a + ' >= ' + val); a; } else { console.log(a + ' < 3 ' + val); val; }";
console.log(eval(code));
This is the scenario where an alternative to eval() is required.
The Server can send any kind of JS code which could be run on a particular block.
Do not use eval(code) or new Function(code) as both are basically the same thing and should be blocked by CSP.
Just return your content from the server as content-type: text/javascript then get it into your page with a <script> block or import.
On the server you would have something like (pseudo code, as I don't know what tech stack you're on):
[Route("serverActionReturningCode")]
public string ActionReturningCode()
{
// return the content as JS
Response.Headers.Add("content-type", "text/javascript");
// build the response object as JS
return "window.latestResult = {" +
"a: '" + a + "', " +
"b: '" + b + "', " +
"generatedCode: function() { ... }" +
"};";
}
Then in your page:
<script src="serverActionReturningCode"></script>
<script>
// Now the script above has run and set window.latestResult
console.log('a', window.latestResult.a);
console.log('b', window.latestResult.b);
console.log('function output', window.latestResult.generatedCode());
</script>
This will let you dynamically generate JS functions on the server.
However, if you can avoid the functions and just need to pass values it is a lot simpler to use JSON instead.
It seems to be like there is no way other than to live with eval or change the entire design of the application. Even if we look for any other alternatives, it's going to be the change in the name and syntax. But the security issues are going to be the same. Its the design of the application that JS CodeGen tool in the server will generate JS code snippets and send it via JSON in certain fields which has to be picked and executed in the front-end. But in this design, we can assure one thing that the JS code is generated only at the design time of the user and not at the runtime.
Thanks for your help.
You can do it like this. Using Eval() is not recommended.
function looseJsonParse(obj){
return Function('"use strict";return (' + obj + ')')();
}
console.log(looseJsonParse(
"{a:(4-1), b:function(){}, c:new Date()}"
))
Refer this MDN article https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval
to dig more into it.
While compiling the coffeescript files from ruby script,
Sample code from my application,
$( () =>
rest_api_login((login_ok, userName, userRoles) ->
console.log("login_ok #{login_ok}, userName #{userName}, roles [#{userRoles.join(", ")}]")
vcm.app.userName = userName
vcm.app.userRoles = userRoles
vcm.app.defaultClassifications = []
initialize_templates((loaded_templates) ->
console.log("loaded_templates", loaded_templates)
vcm.app.main_application()
)
)
)
So, there is a difference, when compiling it into js.
Last committed code was about 2-3 years ago and the developer are not in the company who compiled the last file.
There are few changes in compilation, for ex: a!=b is compiled now as !(a==b), so nothing major just the way of compilation.
So, in my compiled file, the output js file is:
$(function() {
return rest_api_login(function(login_ok, userName, userRoles) {
console.log("login_ok " + login_ok + ", userName " + userName + ", roles [" + (userRoles.join(", ")) + "]");
vcm.app.userName = userName;
vcm.app.userRoles = userRoles;
vcm.app.defaultClassifications = [];
return initialize_templates(function(loaded_templates) {
console.log("loaded_templates", loaded_templates);
return vcm.app.main_application();
});
});
});
and earlier compiled file has the following js:
$((function(_this) {
return function() {
return rest_api_login(function(login_ok, userName, userRoles) {
console.log("login_ok " + login_ok + ", userName " + userName + ", roles [" + (userRoles.join(", ")) + "]");
vcm.app.userName = userName;
vcm.app.userRoles = userRoles;
vcm.app.defaultClassifications = [];
return initialize_templates(function(loaded_templates) {
console.log("loaded_templates", loaded_templates);
return vcm.app.main_application();
});
});
};
})(this));
So my js does not have the return statement and the corresponding this keyword which is present in the earlier compiled file.
And this applies to over my complete js file which has over 15000 lines,
Will this type of effect cause hindrance in the functionality of the application?
What if I want to generate the same js generated before?
I tried compiling it with almost all the versions of gem, coffee-script, current compiled version is from 2.2.0. Any help will be appreciated.
The difference is that your new code uses a fat arrow =>, whereas the old one used a normal function declaration with ->. With a fat arrow, this of a newly declared function is bound to be the this of the outer scope. It's really helpful with callbacks.
In this case fat arrow won't have any effect since this isn't referenced and the callback passed to rest_api_login defines a new scope. It's unnecessary and you should just replace the => with ->. This will generate the original code (sans minor language changes).
Okay, so I think I'm derping here again.. I'm using this code in a HTA (for a intranet application) instead of using just a normal HTML page.. when I "submit" my code I get the error message "Object doesn't support this property or method on line: 24 (which is where I close my file (via activexobjects)
HTML page uses:
<input name="Button1" type="button" value="Submit" onclick="getFormContent()" />
My Javascript file (external .js page) :
// Global Variables First!
var AllFormContent
var ManagerValue
function managerValueTrue(ManagerValue) {
ManagerValue = "Yes"
}
function managerValueFalse(ManagerValue) {
ManagerValue = "No"
}
function getFormContent(ManagerValue) {
var Mudkips = document.getElementById('ManagerName');
var ManagerName = Mudkips.options[Mudkips.selectedIndex].text;
var RandomText = document.getElementById('RandomText').value;
var Comment = document.getElementById('Comments').value;
AllFormContent = ManagerName + ", " + ManagerValue + ", " + RandomText + ", " + Comments
writeMyFile();
}
function writeMyFile(AllFormContent) {
var filesys = new ActiveXObject("Scripting.FileSystemObject");
var filetxt = filesys.OpenTextFile("C:\\MyFile.csv", 8) ;
filetxt.WriteLine(AllFormContent);
filetxt.Close;
}
"line 24" refers to "filetext.close" though I imagine it might have to do with "AllFormContent" or a previous line? I've tested the code, I know I get to the writeMyFile function, I know the ActiveXObject works fine.. Any ideas on what I'm derping with here?
Thanks :]
As everyone suggested in the comments but didn't answer, just add parantheses to Close at writeMyFile().
function writeMyFile(AllFormContent) {
var filesys = new ActiveXObject("Scripting.FileSystemObject");
var filetxt = filesys.OpenTextFile("C:\\MyFile.csv", 8) ;
filetxt.WriteLine(AllFormContent);
filetxt.Close();
}
Close is a method of the Scripting.FileSystemObject in JavaScript while it's more like a subprocedure for VBScript. To call functions and methods in JavaScript, you have to close the reference with parantheses while in VBScript it is unnecessary to call a Sub with parantheses and with multiple params it even gives an error (I think?).
There is not alot of documentation for JScript and the ActiveXObjects for WScript, most of it is covered in VBScript so there is often confusion in this aspect.
This is really strange but this code is working fine unless the value entered by the user includes an asterik (*) or other characters like $ or #. The #ticketNumber.Val() is the suspected problem. Some of our id's have an * in them. Any help would be appreciated.
function buttonClicks() {
var action = '/ServiceCall/IsAServiceCall/' + $('#ticketNumber').val() + '?x=' + new Date().getTime();
$('#ticketNumberFilter').hide();
$('#loading').show();
$.getJSON(action,
{ ticketNumber: $("#ticketNumber").val() },
function(callData) {
if (callData.status == true) {
window.location = "/ServiceCall/Show/" + $("#ticketNumber").val();
}
else {
$('#loading').hide()
$('#ticketNumberFilter').show();
$("#ticketListMessage").slideDown("slow");
$("#ticketNumber").val("");
}
});
}
Here's the controller:
When there is an *, the controller never gets hit:
public JsonResult IsAServiceCall(string ticketNumber)
{
IServiceCallService scService = new ServiceCallService();
return (Json(new { status = scService.IsAServiceCall(ticketNumber) } ));
}
My guess is that (as RoBorg suggests), the URL rewriter that is used by the MVC framework considers * to be a special character... I can't be sure of what the problem is, but it seems like you could avoid the issue pretty easily by just removing asterisks before the request and adding them back again on the server-side:
var ticketNumber = $('#ticketNumber').val().split('*').join('&asterisk;');
and server-side you could reverse the process.
A * shouldn't cause a problem but a # will - you should URL-encode the value using encodeURIComponent():
var action = '/ServiceCall/IsAServiceCall/' + encodeURIComponent($('#ticketNumber').val()) + '?x=' + new Date().getTime();
The same goes for your window.location