Please add a way to import and export cookies

Discussions and Tech Support specific to the iMacros Firefox add-on.
Forum rules
Before asking a question or reporting an issue:
1. Please review the list of FAQ's.
2. Use the search box (at the top of each forum page) to see if a similar problem or question has already been addressed.
3. Try searching the iMacros Wiki - it contains the complete iMacros reference as well as plenty of samples and tutorials.
4. We can respond much faster to your posts if you include the following information: CLICK HERE FOR IMPORTANT INFORMATION TO INCLUDE IN YOUR POST
Post Reply
sightunseen
Posts: 67
Joined: Fri Apr 19, 2013 4:54 am

Please add a way to import and export cookies

Post by sightunseen » Thu May 01, 2014 3:11 am

Hello, I would like to be able to export and import cookies in iMacros. I've noticed that some websites have more captchas when I'm using new cookies so I would like to store the cookies for an account somewhere and then restore them when I am running a script for that particular account. Someone else had this idea in 2007 but it was never implemented.

Thanks
skippyto
Posts: 108
Joined: Wed Aug 20, 2008 8:14 am

Re: Please add a way to import and export cookies

Post by skippyto » Fri May 16, 2014 7:06 am

Hi sightunseen !

It's possible in your js using XPCOM coponents : https://developer.mozilla.org/en-US/doc ... ieManager2

Skippyto.
sightunseen
Posts: 67
Joined: Fri Apr 19, 2013 4:54 am

Re: Please add a way to import and export cookies

Post by sightunseen » Fri May 16, 2014 6:13 pm

skippyto wrote:It's possible in your js using XPCOM coponents : https://developer.mozilla.org/en-US/doc ... ieManager2
Thanks I actually figured it out after I posted this I guess I forgot to follow up. You are right CookieManager2 is the way. I copied most of the source code from here:
https://addons.mozilla.org/en-US/firefo ... t/?src=api
Which is in bootstrap.js and very easy to understand. The license is MPL. Now I have an import function and an export function for my code.
chivracq
Posts: 9494
Joined: Sat Apr 13, 2013 1:07 pm
Location: Amsterdam (NL)

Re: Please add a way to import and export cookies

Post by chivracq » Sat May 17, 2014 3:09 am

Any chance you can post a "ready to work" piece of Code for other Users..., answering exactly your original Question...?

Because I had a look yesterday at Skippyto's Link, and I had to think carefully to understand it again, although I read and studied all the Documentation about XPCOM and XUL some 2 years ago when I wanted to make some FF Add-on monitoring CPU and Memory Usage for FF Kernel and per Add-on...
- (F)CI(M) = (Full) Config Info (Missing): iMacros + Browser + OS (+ all 3 Versions + 'Free'/'PE').
- I don't even read the Qt if that (required) Info is not mentioned...!
- Script & URL help a lot for more "educated" Help...
sightunseen
Posts: 67
Joined: Fri Apr 19, 2013 4:54 am

Re: Please add a way to import and export cookies

Post by sightunseen » Sat May 17, 2014 4:35 am

chivracq wrote:Any chance you can post a "ready to work" piece of Code for other Users..., answering exactly your original Question...?
Hello nice to run into you again. I can do that but it's integrated with my other code, so I've cleaned it up as much as possible. The cookie functions are pretty much a cut and paste. The code is licensed MPL.


Create a javascript file and make this the contents:

Code: Select all

/*
"The contents of this file are subject to the Mozilla Public License
Version 1.1 (the "License"); you may not use this file except in
compliance with the License. You may obtain a copy of the License at
http://www.mozilla.org/MPL/1.1/

Software distributed under the License is distributed on an "AS IS"
basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
License for the specific language governing rights and limitations
under the License.

The code for importCookies() and exportCookies() was copied from
Firefox extension Cookies Export/import 1.0 by Ewind.
https://addons.mozilla.org/en-US/firefox/addon/cookies-exportimport

This code is a sample by sightunseen for the iMacros Firefox forum.
Thread: "Please add a way to import and export cookies"
http://forum.imacros.net/viewtopic.php?t=22796
*/


var endl = "\n";


// Return a string containing the formatted error info.
// in: err(Error)
// return message(string)
function formatErr(err)
{
    var message = "--- Exception " + ( err && err.name ? err.name : "<Unknown>") + " ---" + endl;
    
    if(err)
    {
        message += endl + (err.message ? err.message : "") + endl;
        message += endl + (err.stack ? err.stack : "") + endl;
    }
    else
    {
        message += "No error information provided.";
    }
    
    return message;
}


// Log a message to Firefox's browser console.
// https://developer.mozilla.org/en-US/docs/Components.utils.reportError
function console(aMessage) {
    var consoleService = Components.classes["@mozilla.org/consoleservice;1"]
        .getService(Components.interfaces.nsIConsoleService);
    consoleService.logStringMessage("iMacros: " + aMessage);
}


// Log a message to iMacros' display and Firefox's browser console.
function log(message)
{
    iimDisplay(message);
    console(message);
}


// Log a message to iMacros' display, Firefox's browser console and display it via alert()
function logAlert(message)
{
    log(message);
    alert(message);
}


//
//
// wrap all code in a try/catch
//
//
try {
// anonymous function allows use of return statement and making a function call before it's defined.
(function () {

var dateobj = new Date();
var isodate = dateobj.toISOString();
log("Started script " + endl + isodate);

const folder = "C:\\Users\\Username\\Documents\\iMacros\\Datasources\\";



//
// YOUR CODE GOES HERE.
//

exportCookies("cookies.txt");
clearCookies();
importCookies("cookies.txt");




// Import cookies.
//
// return none
// fatal: failed to import cookies
//
// if filename does not exist no cookies are imported
function importCookies(filename)
{
    var file = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile);
    file.initWithPath(folder + "Cookies\\" + filename);
    if(!file.exists())
    {
        console("Cookies filename " + filename + " does not exist!");
        return;
    }
    
    // Open the selected file
    var istream = Components.classes["@mozilla.org/network/file-input-stream;1"].createInstance(Components.interfaces.nsIFileInputStream);
    istream.init(file, 0x01, 0444, 0); // readonly
    // Select nsILineInputStream interface for "readline()" usage 
    istream.QueryInterface(Components.interfaces.nsILineInputStream);

    // Open CookieManager connection
    var cm = Components.classes["@mozilla.org/cookiemanager;1"].getService(Components.interfaces.nsICookieManager2);
    if(!cm){
        throw new Error("Could not load nsICookieManager2");
    }

    var line = {}, cookieNum, fields, hasmore;
    var cHost, cPath, cName, cValue, cSecure, cSession, cExpiry;
    cookieNum = 0;

    do{
        /* One line from cookies.txt looks like ...
        * .google.com  TRUE     /     FALSE      0      someID 4815162342
        *  <host>    <domain> <path>  <ssl>   <expiry>  <name>  <value>
        *    0          1       2       3        4         5       6
        */
        hasmore = istream.readLine(line);
        var fields = line.value.split("\t", 7);
        if(fields.length != 7)
            continue;
        
        // Read needed fields
        cHost    = fields[0];
        cPath    = fields[2];
        cName    = fields[5];
        cValue   = fields[6];
        cSecure  = (fields[3] == "TRUE");
        cExpiry  = parseInt(fields[4]);
        // Expiry == 0 means this is a session cookie
        cSession = (cExpiry == 0);
        // This is so weird! cm.add() won't take cSession=TRUE and cExpiry=0
        // because cExpiry < Today! So we work around this by making the cookie
        // expire Sonntag, Feb. 7 2106 07:28:15. See you then ;-)
        if(!cExpiry)
            cExpiry = 0xffffffff;
        
        // Add that cookie using the CookieManager
        cm.add(cHost, cPath, cName, cValue, cSecure, false, cSession, cExpiry);
        
        cookieNum++;
    }while(hasmore);

    istream.close();
    console("Imported " + cookieNum + " cookies from " + filename);
}


// Export cookies.
//
// return none
// fatal: failed to export cookies
//
// if no cookies exist filename is not written
function exportCookies(filename)
{
    var file = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile);
    file.initWithPath(folder + "Cookies\\" + filename);
    
    var foStream = Components.classes["@mozilla.org/network/file-output-stream;1"].createInstance(Components.interfaces.nsIFileOutputStream);
    foStream.init(file, 0x02 | 0x08 | 0x20, 0666, 0); // write, create, truncate

    var e = Components.classes["@mozilla.org/cookiemanager;1"].getService(Components.interfaces.nsICookieManager).enumerator;

    var cookieNum = 0;
    while(e.hasMoreElements()){
        var cc = e.getNext().QueryInterface(Components.interfaces.nsICookie);
        var cookieInfo = cc.host
            + "\t" + new String(cc.isDomain).toUpperCase()
            + "\t" + cc.path
            + "\t" + new String(cc.isSecure).toUpperCase()
            + "\t" + cc.expires
            + "\t" + cc.name
            + "\t" + cc.value
            + "\r\n";
        foStream.write(cookieInfo, cookieInfo.length);
        cookieNum++;
    }
    
    foStream.close();
    console("Exported " + cookieNum + " cookies to " + filename);
}


// return none
// fatal: iimPlay failed
function clearCookies()
{
    if(iimPlay("CODE:CLEAR") !== 1)
    {
        throw new Error("iimPlay() failed (see sidebar)");
    }
}


// END CODE HERE
})(); // end of anonymous function
} catch(err) {
    var message = formatErr(err);
    console(message);
    throw err;
}
I use Firefox 24 ESR and that's what I tested in so I don't know if it works in the latest Firefox (let me know).

You'll need to modify the folder variable. For reading and writing cookies, Cookies\ is appended to folder so if the folder variable is:
C:\Users\Username\Documents\iMacros\Datasources\
You'll need to create a folder named Cookies in Datasources.

If you import cookies that already exist they are overwritten. I prefer to clearCookies and I have a function for that. You'll see in my example I did:
exportCookies("cookies.txt");
clearCookies();
importCookies("cookies.txt");

clearCookies() function actually clears cookies and cache because it calls iMacros CLEAR. I still don't understand whether or not that clears supercookies, I'm waiting for anyone to get back to me on that.


You can see diagnostic messages in the browser console, and if they're errors you'll also see them in the iMacros display panel.
You can get to the browser console by going here: Tools > Web Developer > Browser Console (CTRL+SHIFT+J)


Here are some log messages to familiarize you. Let's say cookies.txt does not exist for import. In that case there is no failure. You may want to change that. I have it so a message is written to the log:

Code: Select all

[23:50:59.070] iMacros: Started script 
2014-05-17T03:50:59.055Z
[23:50:59.115] iMacros: Cookies filename cookies.txt does not exist!
Here's what importing and exporting looks like when it's successful:

Code: Select all

--
[23:51:51.395] iMacros: Started script 
2014-05-17T03:51:51.386Z
[23:51:51.587] iMacros: Exported 6 cookies to cookies.txt
--
[23:53:12.070] iMacros: Started script 
2014-05-17T03:53:12.062Z
[23:53:12.349] iMacros: Imported 6 cookies from cookies.txt
--
This the error message if your "C:\Users\Username\Documents\iMacros\Datasources\Cookies\" directory does not exist:

Code: Select all

--
[23:54:57.216] iMacros: Started script 
2014-05-17T03:54:57.208Z
[23:54:57.293] iMacros: --- Exception NS_ERROR_FILE_NOT_FOUND ---

Component returned failure code: 0x80520012 (NS_ERROR_FILE_NOT_FOUND) [nsIFileOutputStream.init]



[23:54:57.295] [Exception... "Component returned failure code: 0x80520012 (NS_ERROR_FILE_NOT_FOUND) [nsIFileOutputStream.init]"  nsresult: "0x80520012 (NS_ERROR_FILE_NOT_FOUND)"  location: "JS frame :: chrome://imacros/content/jsplayer.js :: exportCookies :: line 159"  data: no] @ chrome://imacros/content/jsplayer.js:5
It would be great if the developers would add some cookie functions in iMacros. I can't believe hardly anyone else is asking for it!
Post Reply