AEM 6 SP1 - Extending CRXDE Lite to store Password Type


This is NOT a supported way to extend CRXDE Lite, infact afaik there is no supported/documented way to extend CRXDE Lite. If you always truly :) follow best practices in a project, STOP here, do not read further


Goal


Create a Password Type in CRXDE Lite for users to enter passwords (mask characters while typing password type attribute values). Password type values can be stored in plain text or Encrypted on file system. Please comment if you find bugs and a possible fix...

For a supported way to hide passwords (or other attributes) check this post

Demo | Package Install

Password Type in CRXDE Lite




Sample password stored as plain text (eg. author\crx-quickstart\launchpad\config\com\experienceaem\crxde\lite)

service.pid="com.experienceaem.crxde.lite.ExtensionConfig"
testMulti=["hi","there"]
testPassword="Password:password_changed"
testString="hithere"
testLong=L"1"

Sample password stored Encrypted

service.pid="com.experienceaem.crxde.lite.ExtensionConfig"
testMulti=["hi","there"]
testPassword="Password:{d498726918ffd35347bd536b4421915082c97e26074b499d136084ab905ded2c}"
testString="hithere"
testLong=L"1"


Solution


Follow the two steps below to extend CRXDE Lite and add necessary JS code to create Password type. First step is Not Upgrade-Proof, so when you upgrade CQ, the first step may have to be performed again

Step 1 - Update CRXDE Lite Jar

All we do in this step is copy (back it up just in case if something goes wrong) the serialized CRXDE lite jar, open it and add a small chunk of JS code in it so that any extensions we code are loaded by the added JS logic when lite is opened in browser. The following steps are also shown in demo

1) Access bundles console http://localhost:4502/system/console/bundles and find the CRXDE Support bundle





2) Search for the serialized bundle on filesystem and copy it to a temp location (take a backup before you modify). On my AEM 6 SP1 its available in author\crx-quickstart\launchpad\installer (rsrc-com.adobe.granite.crxde-lite-1.0.66-CQ600-B0001.jar-1415034571045.ser)

3) Rename the copied .ser file to .jar (eg. rsrc-com.adobe.granite.crxde-lite-1.0.66-CQ600-B0001.jar-1415034571045.ser -> rsrc-com.adobe.granite.crxde-lite-1.0.66-CQ600-B0001.jar)

4) Open the jar using zip executable (say winrar), open file docroot\js\start.js in any text editor and add following code at the end. Save file and a winrar confirmation should popup asking if the jar should be updated with saved file.

Ext.onReady(function() {
    var loadLiteExtns = function(){
        Ext.Ajax.request({
            url: "/apps/ext-crx-delite/files.txt",
            success: function(response, options) {
                var js = response.responseText;

                if(!js){
                    return;
                }

                js = js.split("\n");

                Ext.each(js, function(jsPath) {
                    Ext.Ajax.request({
                        url: jsPath,
                        success: function(response, options) {
                            eval(response.responseText);
                        }
                    });
                });
            }
        });
    };

    CRX.util.Util.on("reinit", function(){
        location.reload();
    });

    loadLiteExtns();
});


5) In the above steps we add necessary code to load the extension files entered in /apps/ext-crx-delite/files.txt. So whenever a new CRXDE Lite extension is needed a new line with extension file path can be added in /apps/ext-crx-delite/files.txt

6) Access http://localhost:4502/system/console/bundles, click Install/Update... to upload and update CQ with the new CRXDE Support jar having necessary code to load the CRXDE Lite extension files.

Step 2 - Add extension files in CRX

In this step we add the JS file containing logic to create a Password type (like String type)

1) Access http://localhost:4502/crx/de

2) Create node /apps/ext-crx-delite of type nt:folder

3) Create node /apps/ext-crx-delite/files.txt of type nt:file and add the following line. The logic added in Step 1 reads this file for loading JS extension files added as paths

                                 /apps/ext-crx-delite/hide-password.js

4) Create node /apps/ext-crx-delite/hide-password.js of type nt:file and add the following code

Ext.ns("ExperienceAEM");

ExperienceAEM.PASSWORD = "Password";

ExperienceAEM.PropertyPanel = Ext.extend(CRX.ide.PropertyPanel,{
    MASK: "****",

    constructor: function(config){
        ExperienceAEM.PropertyPanel.superclass.constructor.call(this, config);

        var eThis = this;

        this.types.store.loadData([ExperienceAEM.PASSWORD],true);

        var valueColumn = this.getColumnModel().getColumnById("value");

        valueColumn.renderer = function(value, p, record) {
            var rValue = Ext.grid.Column.prototype.renderer.call(this, value, p, record);

            if( (typeof rValue) != "string"){
                return rValue;
            }

            var indexOfPassword = rValue.indexOf(ExperienceAEM.PASSWORD + ":");

            if( indexOfPassword == 0){
                record.data.type = ExperienceAEM.PASSWORD;
            }

            return (record.data.type == ExperienceAEM.PASSWORD) ? eThis.MASK : rValue;
        };
    },

    initValue: function() {
        ExperienceAEM.PropertyPanel.superclass.initValue.call(this);

        this.value[ExperienceAEM.PASSWORD] = {
            xtype: "textfield",
            inputType: "password",
            allowBlank: true,
            disableKeyFilter: true,
            cls: "x-form-text",
            tabIndex: 102
        };
    }
});

Ext.reg("propertypanel", ExperienceAEM.PropertyPanel);

(function(){
    var handler = CRX.ide.SaveAllAction.initialConfig.handler;

    CRX.ide.SaveAllAction.initialConfig.handler = function(){
        var workspaces = CRX.Util.getWorkspaces();
        var dirtyPassRecs = [];

        workspaces.each(function(workspace) {
            var paths = CRX.State.getChangedPaths("/" + workspace + "/");

            if (paths.length == 0) {
                return;
            }

            Ext.each(paths, function(path){
                var records = CRX.State.getPropertyRecords(path);

                Ext.each(records, function(record) {
                    if ( (record.data.type !== ExperienceAEM.PASSWORD) || !record.dirty){
                        return;
                    }

                    record.data.type = CRX.util.STRING;
                    //comment the below line if you use encryption
                    record.data.value = ExperienceAEM.PASSWORD + ":" + record.data.value;

                    dirtyPassRecs.push(record);
                });
            });
        });

        var words = [];

        Ext.each(dirtyPassRecs, function(record) {
            words.push(record.data.value);
        });

        /*
        uncomment this block to use encryption
        //http://experience-aem.blogspot.com/2014/11/aem-6-sp1-servlet-for-encryption-decryption.html
        Ext.Ajax.request({
            url: "/bin/experienceaem/encrypt?words=" + words.join(","),
            success: function(response) {
                var words = JSON.parse(response.responseText);

                Ext.each(dirtyPassRecs, function(record) {
                    record.data.value = ExperienceAEM.PASSWORD + ":" + words[record.data.value];
                });

                handler();

                Ext.each(dirtyPassRecs, function(record) {
                    record.data.type = ExperienceAEM.PASSWORD;
                });
            }
        });*/

        //start: comment the below lines to use encryption
        handler();

        Ext.each(dirtyPassRecs, function(record) {
            record.data.type = ExperienceAEM.PASSWORD;
        });
        //end:
    }
})();


5) Make sure logic strips off the leading Password: string when reading a stored password, from CRX, to get the actual password (further if password is encrypted, make sure you decrypt it before using...)

11 comments:

  1. Business information systems research paper services have become very popular for students studying business & information technology coursework as they engage the best online Information Systems Writing Services.

    ReplyDelete
  2. I don't order the work at essay pro reviews as often (2-3 per semester), but I have been ordering stably for four consecutive years. For this period any author has not let me down: all works I have received in time, plagiarism in them I have not found.

    ReplyDelete
  3. Having found a girlfriend on the site asian brides, I recommend it to all my friends who have problems with choosing an Asian girl.

    ReplyDelete
  4. Nothing keeps me here other than your affordable prices and accurate solutions. After all, they're the best things any other student can get from a Programming Homework Help service provider like you. Meanwhile, I also admire your experts' speed and professional conduct. No other similar service can beat yours according to my experience. Thanks a lot for giving me the best Java Homework Help services. I'll come again for more.

    ReplyDelete
  5. Your Matlab Assignment Help expert's speed was the best for my emergency order. He was a Master's degree holder in software engineering, so I expected the best from him, which he delivered. While I wasn't after an A with the short notice, he delivered it! Amazing! I've been on many Matlab Homework Help platforms but never have I received help from such a guru. I've marked him as my favorite programming assignment helper.

    ReplyDelete
  6. Economicshomeworkhelper.com is one of the rare websites that a visitor can navigate without asking for help. That's exactly what I did when I ordered the first Economics Homework Help from you. I placed an order perfectly without even contacting your customer care team. I then received your quote, paid for the order via your secure page, and waited around 20 minutes before the order was assigned to one of your able Economics Assignment Help experts. The outcome was great.

    ReplyDelete
  7. Hi there, 온라인카지노 I found your blog by the use of Google while looking for a related subject,
    your site came up, it appears good. I've bookmarked it in my google bookmarks.

    ReplyDelete
  8. 바카라사이트 You present a very well-written article and with some awesome information which is very helpful, like me as reader. Thanks for sharing it and also
    please visit our great site below.

    ReplyDelete
  9. Thanks for this helpful article. Looking forward to having my portfolio. 스포츠토토
    You can also read some of my great reviews about Best

    ReplyDelete
  10. 토토 I constantly spent my half an hour to read this web site’s content daily along with a cup
    of coffee.

    ReplyDelete
  11. You, people, are doing fantastic work here, and I must say this blog has been my best source of information, and I really want to thank you for doing a nice job in this blog  kwasu post utme past questions and answer pdf

    ReplyDelete