четвъртък, 27 август 2015 г.

Get rid of crossdomain origin errors.

When developers work on web applications under Windows there are often crossdomain  origin errors. The old version of  Google Chrome browsers provides a  usefull feature
--disable-web-security command line argument for  chrome.exe but unfornatelly this option was deprecated.  When you try to use it under current version of Chrome
- Version 44.0.2403.157 m you will get the following error:
"You are using an unsupported command-line flag:   --disable-web-security. Stability and security will suffer.". I tried to download current Chromium build   but with no luck - this errors appear again. After a small time thinking I'm came to a solution that I want to share with other people with a similar problem. I download Opera that is based on Chrome. Under Opera this command line option
 works like a charm and you have the same tools available.  Even an emulator for mobile devices.


Here is small demo. Get response from yahoo when google is open. Executing of this small snippet
from console.

(function() {
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
console.log(xhr.responseText);
}
}
xhr.open('GET', '//www.yahoo.com/', true);
xhr.send();
}());

And here is the result: 


But if you want to use just a Google Chrome I write this script to make the starting of Google Chrome browser without security much easier than it was before. The script checks if there is running instances of chrome.exe and if there is a present instance, alerts the user that the running instance must be killed before Google Crome is started. If the user clicks on Yes button, the script will kill all instances of chrome.exe. After this, will open a new browser instance without security. If the user clicks on No button, the script will do nothing. If there is no present running instance of chrome.exe, the script will start Google Chrome without security. How to use it? Just clone this repository and fill correct path to chrome.exe. The script is tested on windows 8 with admin rigths. Don't hesitate to write to me with suggestions and feature requests.
https://github.com/gonaumov/chromeRunner

събота, 13 юни 2015 г.

Cucumber-js and Chai how to expect if element with given selector exist in DOM

This week I had one problem with protractor and cucumberjs. I read protractor documentation and asked question into stackoverflow. I want to share one very small learned lesson here also. If you want to expect if element with a given selector exist in DOM you must use isPresent() it returns a promise that will resolve to whether the element is present on the page.

    element(by.id('someId')).isPresent().then(function(isElementVisible) {
         expect(isElementVisible).to.be.true;   
    });
 
Or use chai with promises.

    expect(element.isPresent()).to.eventually.be.false
 
However, the word "eventually" sounds unpleasant. We want to be sure not eventually sure. :)
Here can be viewed the quesion into stackoverflow.  

вторник, 2 юни 2015 г.

Емилиян Кърчев и http://energyaudit.bg

Емил или за възпитанието. Горкият Русо. Това е цитат от Богомил Райнов. Не е измислен от мен. Викнахме въпросният господин да направи експертиза на един теч, който излезе в следствие на направен ремонт. Решихме, че сайта му е най-представителен и изглежда най-професионално от всички. На сайта на господина няма цени. Казал е на жена ми цена от 138лв. Аз дойдох след работа, за да може да се извърши диагностиката, но не бях чул добре цената, която трябва да се плати.  Бях чул нещо от сорта на 174лв. Е дадох му 180лв с идеята, че ще си хване, колкото му трябват. Господина си ми пусна касова бележка за 180лв. След това разправял на жена ми, че за да ни пусне констативен протокол трябвало да чукне още 48лв а снимките се обработвали със специален софтуер. Не, че е кой знае какъв проблем де, но е важен принципа в крайна сметка. Браво Емо. Тия 50лв. да ги дадеш за лекарства. Ето го и сайта на господина.
Промяна от 04.06.2015г.
Да допълня. Това, че няма цени на сайта не отговаря на истината. Мое недоглеждане. Денят ми беше твърде зает, за да гледам сайта на господина. По тази причина и му дадох 180лв с идеята да си хване колкото е цената, както съм писал по-горе. Притежавам и касова бележка за сумата. По долу показвам и текущите цени на сайта на господина.
Сметката пак не излиза. При промяна цените спрямо тази дата (03.06.2015г) могат да бъдат извлечени от всеки кеш на търсеща машина.

неделя, 5 октомври 2014 г.

Bot for sexgangsters game.

I love to write user scripts. These days I have some fun to write bot for a very nice online game. From the programming perspective interesting part is the use of MutationObserver, with his help the programmer easily can detect changes in the DOM structure.
I made the bot as a add-on for Mozilla Firefox and set as a project in github. There are some issues, which I'll fix in my spare time.
https://github.com/gonaumov/sexGangstersBizBot

вторник, 12 август 2014 г.

Dynamic routing in AngularJS App.config method.

Some time ago I had a work task required to make dynamic routing in App.config method of AngularJS application. Initially I wanted to do something like this:

someApp.config(['$routeProvider', '$httpProvider', 
    '$compileProvider', 'settings',
    function ($routeProvider, $httpProvider, 
        $compileProvider, settings) {

        var $http = angular.injector(['ng']).get('$http');
        var $q = angular.injector(['ng']).get('$q');
        var isUserLogged = $q.defer();

        $http.get(settings.apiUri + settings.loginStatus).
          success(function (data) {
            if (data.status == "NOT_LOGGED") {
                isUserLogged.reject();
            } else {
                isUserLogged.resolve();
            }
        });

        isUserLogged.promise.
          catch(function () {
             $routeProvider.
                 when('/home', {
                     templateUrl: 'partials/home.html',
                     controller: 'HomeController'
                 }).
                 otherwise({
                 redirectTo: '/home'
             });
        });

        isUserLogged.promise.
         then(function () {
            $routeProvider.
                when('/accountsettings', {
                    templateUrl: 'partials/accountsettings.html',
                    controller: 'AccountSettingsController'
                }).
                otherwise({
                    redirectTo: '/accountsettings'
                });
        });
    }]);

But routing did not work because .config method behaves as synchronous. When I remove the http query and promice logic everything worked perfectly. I asked a question in stackoverflow, but there was no answer. After reading the documentation and digging I came to the decision that satisfy me. I did a manual bootstrapping of the application. First I make request to determine whether the user is logged or not. Then I trigger custom event listener whose call .config method of application and do routing in accordance whether the user is logged or not. Below is the code of the decision to which I got (with abbreviations).

angular.element(document).one("userStatusIsCheked", 
                        function(event, userIsLogged) {
    appName.config(['$routeProvider', 
        '$httpProvider', '$compileProvider',
        function ($routeProvider, 
         $httpProvider, $compileProvider) {
            if (userIsLogged == true) {
                $routeProvider.
                    when('/resetpassword/:hashValue', {
                        templateUrl: 'partials/home.html',
                        controller: 'ResetPasswordController'
                    }).
                    when('/accountsettings', {
                        templateUrl: 'partials/accountsettings.html',
                        controller: 'AccountSettingsController'
                    }).
                    when('/changepassword', 
                      {
                        templateUrl: 
                        'partials/accountsettingschangepassword.html',
                        controller: 'ChangePasswordController'
                    }).
                    when('/edit', {
                        templateUrl: 'partials/accountsettingsedit.html',
                        controller: 'EditAccountController'
                    }).
                    when('/apikeymanagement', {
                        templateUrl: 'partials/apikeymanagement.html',
                        controller: 'APIKeyManagementController'
                    }).
                    when('/dashboard', {
                        templateUrl: 'partials/dashboard.html',
                        controller: 'DashboardController'
                    }).
                    when('/pipelines', {
                        templateUrl: 'partials/pipelines.html',
                        controller: 'PipeLinesController'
                    }).
                    when('/preferences', {
                        templateUrl: 'partials/preferences.html',
                        controller: 'PreferencesController'
                    }).
                    when('/reports', {
                        templateUrl: 'partials/reports.html',
                        controller: 'ReportsController'
                    }).
                    when('/logout', {
                        templateUrl: 'partials/logout.html',
                        controller: 'LogoutController',
                        resolve: {
                            logout: function (logout, $q) {
                                var deferred = $q.defer();
                                logout()['finally'](
                                    function() {
                                        deferred.resolve();
                                    }
                                );
                                return deferred.promise;
                            }
                        }
                    }).
                    when('/privacy', {
                        templateUrl: 'partials/privacy.html',
                        controller: 'PrivacyController'
                    }).
                    when('/tos', {
                        templateUrl: 'partials/tos.html',
                        controller: 'TosController'
                    }).
                    when('/currentStatus', {
                        templateUrl: 'partials/currentStatus.html',
                        controller: 'CurrentStatusController'
                    }).
                    otherwise({
                        redirectTo: '/dashboard'
                    });

            } else {
                /**
                 * If user is not logged default action is
                 * home.
                 */
                $routeProvider.
                    when('/home', {
                        templateUrl: 'partials/home.html',
                        controller: 'HomeController'
                    }).
                    when('/resetpassword/:hashValue', {
                        templateUrl: 'partials/home.html',
                        controller: 'ResetPasswordController'
                    }).
                    when('/privacy', {
                        templateUrl: 'partials/privacy.html',
                        controller: 'PrivacyController'
                    }).
                    when('/tos', {
                        templateUrl: 'partials/tos.html',
                        controller: 'TosController'
                    }).
                    when('/currentStatus', {
                        templateUrl: 'partials/currentStatus.html',
                        controller: 'CurrentStatusController'
                    }).
                    otherwise({
                        redirectTo: '/home'
                    });

            }
        }]);

        angular.bootstrap(document, ['appName']);
});

angular.element(document).ready(function() {
    var injector = angular.injector(['appName']);
    var settings = injector.get('settings');
    var $http = injector.get('$http');

    var functionFactory = function (userStatus) {
        return function () {
            this.lUserStatus = userStatus;
            return this.lUserStatus;
        }
    };

    /**
     * So here we will check if user is logged or
     * not and after this construct conditional routing
     * into config method (above).
     */
    $http.get(settings.apiUri + settings.loginStatus).
             success(function (data) {
        if(angular.isDefined(data.status) && 
            data.status == "NOT_AUTHENTICATED") {
            appName.service('userIsLogged', functionFactory(false));
            angular.element(document).trigger("userStatusIsCheked", [false]);
        } else if(angular.isDefined(data.status) && data.
                status == "AUTHENTICATED") {
            appName.service('userIsLogged', 
            functionFactory(true));
            angular.element(document).trigger("userStatusIsCheked", [true]);
        }
    });
});


Hope this helps someone with a similar problem.

New site dedicated to web development

My wife and I started to create a website dedicated to the development for the web. We hope that this site will be useful to all interested in the subject design and programming. http://codinghunters.com/

събота, 24 май 2014 г.

Bulgarian state institutions - a home for slackers and incompetents.

I am writing this material reluctantly. Unfortunately, in Bulgaria people that work in important state institutions are mostly illiterate and irresponsible. Yesterday I was shocked by a criminal negligence. Ministry of Education and Science is maintaining a web site service , located at this url: http://www2.mon.bg/adminrhe2/. In the question url, user can checks whether there are any university diploma on his behalf. Me, who last year defended a thesis in SULSIT as an upgrade over professional bachelor, did check that I have been in the register and noticed something that made me 'amazed' (I'm a web developer with years of experience). It's that uniform civil numbers of the users are sent to the system for inspection, using uncoded Protocol (http). This means that each route to a question asp script (http://www2.mon.bg/adminrhe2/default.asp), eg ISP user can access and capture sensitive personal information. This information is confidential and extremely important for the user. The screenshot below shows how easy it is to be caught this element of the request. I hid only the last digits of my number to protect my safety.
That so called "technical support", which takes place within the project "Information and telecommunication technologies in education" or ICT in Education (BG051PO001/3.1-01), is implemented by the Bulgarian company AdminSoft. Who knows how much money had been sunk into this project, which obviously was made by incompetents. My wife wrote this into a facebook group 'Marketing and Webmastering' and there was immediate reaction by an internet blogger, who wrote an article, explaining the importance of HTTPS and where were given another examples of the government institutions websites, which also don't have encryption.
The story has a sequel. I sent a complaint to the Bulgarian Commission of Protection of Personal Data, and after six months I received a response from them. I'm attaching here the document received by them only hiding my address and theirs documentation numbers. This document confirms that there was indeed a problem and it was resolved after intervention by the Commission.