OneWay WPF binding Trap

I'm sure you've used WPF binding. There are five BindingMode: Default, OneTime, OneWay,  OneWayToSource, and TwoWay.

OneWay is best for read-only property. But if it's not done correctly, it'll break the binding and the target won't be updated.

Here's how it's broken: call SetValue on the control to set the target directly. What happens here is that WPF will set the value of the target to the one passed in SetValue. That will overwrite the binding. Since the binding is OneWay, WPF cannot set the source, so it need to remove the binding to set the value. After that, even if the source is updated, the target sill stay the same. With that in mind, we must not throw exceptions in the setter of the source and the converter if that exists.

This is something we need to take into account when we set up OneWay binding. Always update the source, instead setting the target. If you're creating a library and set a dependency property on the control directly, you're setting the trap to your library users. This is rather difficult to debug.

Ionic Framework Select on Windows 10 Mobile

There's a problem in touching a select element on Microsoft Edge or on Windows 10 Mobile app.
When you touch the select element, it won't open the options or the options are open twice.
It seems to be interfered with Ionic Framework's tapping (http://ionicframework.com/docs/api/page/tap/).
The solution is simple: disabling the tab system.
For select element, I use

<select data-tap-disabled="true" ...></select>

That solves the problem. Tapping on the select element will open the options correctly.

Manage States between Routes in Angular

I use ui-router (https://github.com/angular-ui/ui-router) to route the url to state. For each state, we can specify the controller and the view. When transitioning from one state to another, we need to pass some data.

The way to specify a state is

$stateProvider.state('StateName', {
    url: 'request url',
    templateUrl: 'html file path'
})

There are a few ways to pass data to the state.

  1. Set the parameter in the url. For example, "contacts/{contactId}".  And use $stateParams to get the value. For example, $stateParams.contactId.
  2. In some cases, we don't want to specify parameters in url. Then we still can specify parameters in the state. e.g.
$stateProvider.state('StateName', {
    url: 'request url',
    params: {
       param1: null,
       param2: null
    },
    templateUrl: 'html file path'

Then you still can use $stateParams.param1 or $stateParams.param2 to get the values.
The way to set the parameter is:

$state.go('StateName', {param1: 'params Value'});

That's it. We can pass various parameters to the same url and the state should be able to handle it.

My First Cordova Project

I developed a mobile app recently. VS is an excellent tool in managing the project and debugging. I would like to start from setting up the project in VS, followed by my experience in my mobile development journey.

The app is a bookkeeping of your investment. Your investment can be in the brokerage account, retirement account or HSA. Besides bookkeeping, it also calculates the rate of investment.

First of all, I use Visual Studio 2015 Community with Apache Cordova Tool. I chose to install Windows phone 10 SDK. You can install the Android emulator and the Android SDK. It's up to your target platform.

VS Installtion screenshot

Note that even though you just want to target Windows 10 and Windows Phone 10, you still need to install Windows Phone 8.1 Tools and SDKs. Otherwise you won't be able to debug it on your Windows 10 Phone. It complains that bin/arm/dbghelp.dll is not found and it comes with Windows Phone 8.1 Tools.

Framework can improve productivity and accelerate development. It provides the backbone of the application and glue all major parts together. I just need to follow the pattern and fill in the parts. I chose Ionic framework.

What UI is suitable for this app? Ionic provides some templates: simple, tabs and side menu. I think side menu provides the largest real estate on the screen, while flexible in navigation.

It's easy to create an Ionic project in VS. In the "New Project" dialog, search Ionic in the Online tab, then download the one you like.

VS search Ionic template screenshot

After the template is downloaded, you need to re-open "New Project" dialog, and Ionic project templates are in the Installed tab.

VS new Ionic project screenshot

Since it's bookkeeping, it needs to persist the data. Sqlite is suitable in the mobile application. I found a plugin at GitHub (https://github.com/litehelpers/cordova-sqlite-ext.git).

In VS, open config.xml (View Designer), then add a custom plugin. Use the git repository and install it. VS Cordova add plugin screenshot

So far, I've set up the project.  The journey has started.

Setting Up CSF on VPS

I recently noticed my VPS is slow. The blog takes a long time to show me any content. When I log in vis SSH, I usually don't see what I type in immediately. The command is echoed a few minutes later.

I started my investigation. I ran 'top'. CPU doesn't run crazily. Memory isn't loaded heavily. There's no suspicious process. Everything looks good. But the connection is still slow! I asked the VPS provider. Hey, why is my VPS slow to respond when CPU and memory aren't overloaded? The support team took a look and responded to me with one IP address 191.96.249.54 that established many connections to my VPS. I then searched the IP address online and found this StackOverflow question (http://serverfault.com/questions/778831/how-to-block-an-attack-on-wordpress-using-ufw-on-ubuntu-server). It's an attack! Somebody suggested to use ipsest to add a blacklist. Probably that's the way to go, because when I looked at Apache log, there's also connection from 191.96.249.53. They're from the same organization.

I found the solution. I installed ipset to find out that it didn't run. I got this error:

ipset v6.11: Cannot open session to kernel.

Some articles online say it needs kernel patching. But I don't control kernel on my VPS. So I contacted my VPS provider again. We couldn't just upgrade the kernel. But they suggested me an alternative solution: CSF (http://www.configserver.com/cp/csf.html).

CSF can do what ipset does. I just need to use the blacklist. Besides, it can monitor user log in and inform you when somebody tries to log in in a short time to figure out the password. There are other protections too. All are documented in the readme file. The configuration file contains explanation for all options. It is a lot of information to digest and you have to make your own choice. I'll just put down some basic points:

  1. Set TESTING to 1 first. The value 1 will have CSF stop itself 5 minutes  after it's started. So when you accidentally lock yourself out, you still can gain access to your VPS after at most 5 minutes.  Remember to set it back to 0 when you've tested your configuration file.
  2. TCP_IN and UDP_IN are the ports that incoming connections are allowed to connect to. At least, put your SSH port number in TCP_IN so that you still can access  to your VPS.
  3. On my system, CSF can't find /usr/bin/host. It's in its log file. Remember to check the log file for any errors and fix them.
  4. csf.deny contains a list of IPs from where the incoming connection are dropped. It supports CIDR notation (https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing#CIDR_notation). I put the suspicious IP addresses in this file.

After CSF starts to run. There is no connection from the suspicious IPs any more from Apache log file. The connection to my VPS is fast again.