Event Chaining Framework in JavaScript

Stainless-Steel-Chain

Asynchronous code flow is notoriously difficult to follow. With the deprecation of synchronous Ajax calls and increasing use of concurrent code in JavaScript, we often need to have functions execute in a step by step process via chaining.

This article presents a short solution to chaining asynchronous code in JavaScript. I wrote a small event manager in JavaScript using the principals defined in the article.

Deferred

The JQuery Deferred object acts much like promises and futures in more powerful object orient languages such as Java and Scala. A deferred object is created and used to call a function or chain of functions as needed.

var dfrd = $.Deferred();
dfrd.then(func1).then(function(result){
    console.log(result);
});
dfrd.resolve('result');

A deferred object works in exactly the same way as a JQuery Ajax call and uses the same method to handle an asynchronous method call. The created deferred can be chained using .then which allows for a result to be passed via .resolve.

A deferred object must be resolved to execute a chain. The .then method allows for not only a callback to be executed on success, but failure and progress callbacks to be executed as well.

Nesting Problem With JQuery Solutions

Nesting is messy. Unfortunately, with the JQuery solution, it is impossible to chain deferred functions without nesting them.

$.when(func1()).then(function(result1) { 
    $.when(func2(result1)).then(function(result2) {
        alert(result2);
    }) 
});

With this solution, the deferred method waits on another result before executing the next function. The call to .when allows for a promise to be utilized.

Custom Chaining Solution

While nesting is useful, it is not always the cleanest solution. Another option is to create a stack and then pop from the stack while generating a new chain.

function get_chain(step, previous_chain){
    var to = step.timeout;
    var func = step.func;
    var new_chain =  $.Deferred();
    if(to > 0){
        new_chain.then(function(result){
            return execute_step_timeout(to, result);
        })
    }
    new_chain.then(function(result){
           return func(result);
    });
    if(previous_chain){
        new_chain.then(function(result){
            previous_chain.resolve(result);
        });
    }
    return new_chain;
}

Here, a function takes a step configuration containing any deferred timeout and a previous chain and constructs a new chain.

Such a process is akin to writing the following code:

var nchain = $.Deferred()
nchain.then(function(result){
	return execute_step_timeout(1, result);
}).then(function(result){
	return func2(result);
}).then(function(result2) {
    	    alert(result2);
});

$.when(func1()).then(function(result1) {

Conclusion

Asynchronous Javascript, while not parallel, often requires chaining. This article reviewed how this can be done cleanly using the JQuery Deferred object.

 

Better Key Storage With Blackbox, RSA, Redis, and the Fernet Algorithm in Django

safe

Python lacks a proper key store.  This is an unnerving issue when trying to build a secure application. More troubling is the plain text storage of RSA keys. This article examines a process for storing keys in an encrypted manner on black box as well as the storage of keys using the Fernet algorithm and encryption through RSA in Django using redis for speed.

Problem

Unlike Java which already has a key store, Python lacks the ability to store keys for data encryption. Python developers are left with only basic methods for storing keys and this often means doing so in plain text.

That method is inexplicably terrible when working with FERPA/HIPPA and especially the increasingly difficult state guidelines for storing sensitive information.

Solution

One solution, of many, is to use Stack Exchange black box to store keys and the Fernet algorithm to encrypt the keys in a cache. In this way keys are stored in an encrypted format in a hidden file as well as in a secure format in memory.

Black Box

Stack Exchange’s Black Box offers a perfect storage solution for keys using a gpg keyring to encrypt data. The tool was made to store secrets in a git repository.

Check out my Python API for reading files from black box. It is possible to add a user to the administrator file in order to avoid entering a password each time.

Storing Encrypted Keys in Django

Once the keys are encrypted and accessible, a large application needs to ensure speed. To help alleviate sluggishness, it is possible to store keys using the Fernet algorithm in any cache that Django provides.

It is possible to use the cryptography package for this task.

from cryptography.fernet import Fernet
from django.core.cache import cache

key = Fernet.generate_key()
f = Fernet(key)
token = f.encrypt(b"my deep dark secret")
cache.set('my_token', token)

Conclusion

It is possible to recreate a secure keystore using a mix of Stack Exchange Black Box and the Fernet algorithm when creating a Django application. The implementation above may not be production ready but is a proof of concept.

Encrypting Data in Django with the Fernet Algorithm

lock

At some point, it will be necessary to encrypt data. While most queries are performed raw, there is still a use for the models Django provides in encrypting and decrypting data or even just in obtaining a model from a raw query.

This article examines how to apply the Fernet algorithm to save data in an encrypted format using Django.



 

Fernet Encryption

Fernet encryption utilizes the AES method at its core. This method is widely accepted and more powerful than RSA when there is no need for communication.

RSA is a powerful tool when requiring that data be passed over the wire. In this example, we are more concerned with data storage.

Secret Key

The Fernet algorithm requires using a secret key to store data.

from cryptography.fernet import Fernet

Fernet.generate_key()

This key should be stored in a secure fashion. Options for retrieving the key include loading the key from a file passed through an environment variable.

Encrypted Field

Django provides an excellent tutorial for writing custom fields. By overwriting the from_db_value and get_db_prep_value methods it is possible to achieve decryption and encryption respectively.

HOME = str(Path.home())


class EncryptedFernetField(models.TextField):
    """
    A field where data is encrypted using the Fernet Algorithm
    """

    description = "An encrypted field for storing information using Fernet Encryption"

    def __init__(self, *args, **kwargs):
        self.__key_path = os.environ.get('FERNET_KEY', None)
        if self.__key_path is None:
            self.__key_dir = os.environ.get('field_key_dir', None)
            if self.__key_dir is None:
                self.__key_dir = os.path.sep.join([HOME, 'field_keys'])
                if os.path.exists(self.__key_dir) is False:
                    os.mkdir(self.__key_dir)
            key = Fernet.generate_key()
            with open(os.path.sep.join([self.__key_dir, 'fernet.key']), 'w') as fp:
                fp.write(key.decode('utf-8'))
            self.__key_path = os.path.sep.join([self.__key_dir, 'fernet.key'])
        super().__init__(*args, **kwargs)

    def deconstruct(self):
        name, path, args, kwargs = super().deconstruct()
        return name, path, args, kwargs

    def from_db_value(self, value, expression, connection):
        if self.__key_path and value:
            value = base64.b64decode(value)
            with open(self.__key_path, 'r') as fp:
                key = fp.read()
            f = Fernet(key)
            value = f.decrypt(value)
        return value

    def to_python(self, value):
        return value

    def get_db_prep_value(self, value, connection, prepared=False):
        if value:
            if self.__key_path:
                with open(self.__key_path, 'r') as fp:
                    key = fp.read().encode()
                f = Fernet(key)
                value = f.encrypt(value.encode())
                value = base64.b64encode(value).decode('utf-8')
        return value

Encrypted values are stored in base 64 to avoid potential byte related issues. This class utilizes the models.TextField to save data as a blob.

Using the Field

The field is used in the same way as any other.

class License(models.Model):
    username = models.CharField(max_length=1024)
    application = models.CharField(max_length=1024)
    unique_id = models.IntegerField(unique=True)
    license = EncryptedFernetField()
    active = models.BooleanField(default=False)
    expiration_date = models.DateField()

    class Meta:
        unique_together = (('username', 'application'), )

 

Conclusion

Data encryption is fairly straightforward in Django. This tutorial examined how to create an encrypted field using the Fernet algorithm.

WebFlow Designer: Mediocre at Best

disappointed-face_1f61e

Web Flow is one of several visual HTML editors to come on the market in the hopes of replacing Komodo or Dream Weaver. While promising, it may be best to wait for Framer X before purchasing a visual editor.

Since the creation of Wix and the corresponding Wix editor, the idea of giving designers a no-code way to develop web pages has taken root in the development community. The reason such tools have not gained much in the way of popularity is easily apparent with Web Flow.

To be certain, Web Flow contains quite a bit of promise as both a design tool and CMS for simpler websites. The live content editors in particular are a nice to have for teams of any size.

The pros of Web Flow can be summed up as follows:

  • simple, fast, and live development for simple websites
  • basic editing support
  • basic script and style support through an embed tag
  • can be cheaper than a tool such as Dream Weaver for smaller organizations
  • can connect to article-style and other forms of data not requiring heavy back-end support

Just from the pros, it is obvious that a visual editor is perfect for the rapid prototyping associated with the design sprint concept. This is also not a difficult tool to create when considering the current power of Javascript and JQuery, especially when supporting a Mozilla based browser.

For each of the positive characteristics of Web Flow, there is at least one downside:

  • only allows style and script editing in an embed tag
  • contains almost no support for external CSS files
  • cannot be installed on site and does not use a company database
  • fails to provide advanced CSS features beyond a box shadow or border radius
  • class editing cannot be done separately from the generation of an element
  • a parent element must first be created to generate a new class
  • promotes sloppy, terrifying CSS that a middle-ware developer will quit over
  • is not drag and drop and has almost no such support in the editor

Basically, Web Flow and even tools such as Framer area far from ready for the production of modern websites.  Still, if you need to give a designer access to any form of tool that allows for inheritance based web editing or need slightly more than Wikipedia or Wix, Web Flow is decent. Still, Framer X promises to be a much better tool.

This tool, in the current form, is at best a 5/10. It is an average effort from what I hope is not an arrogant fool as can be the case with people who don’t want to actually work on their product that I at least hope will continue to improve to an 8 or 9 of 10.

 

 

 

Fixing Floating Parent Divs

It is frustrating  to float a child element only to find that every element appears to take the same positioning or find the child spilling beyond the borders of the parent. This brief article presents a modern solution to this issue using the display attribute in CSS.

Problem

At times when using the float attribute, elements placed in siblings  to a parent tag or even the siblings appear to inherit the floating properties of the target element. Elements may also appear to expand beyond the boundaries of a parent tag.

There are a few root causes of an element causing the parent’s siblings to appear to float including:

  • the zero height problem where an element is larger than its parent
  • the width of an ancestor is specified and violated by the child element

Solution

An older solution to the issue is to use the clear fix hack. However, with modern browsers, the solution is simpler:

.textedit-stylesheet-attr-div{
    display: flow-root;
}

Specifying flow-root causes the block format to be followed for the elements in the parent. This will maintain the float property of the children and cause the parent to ‘fit’ the child elements.

Using :before or :after in CSS, adding a border to a clipped path

Clip path is great but there is an issue. The border property stops working. Triangles, polygons, and nearly any shape can easily be produced. However, the borders are cut.

This short article examines how to resolve this problem with pseudo images, introducing before and after.

Problem

CSS renders the clip path last no matter how it is placed in a CSS class or in what order classes are arranged. This means that margins, borders, and other features are lost when the object is clipped.

Before and After

The solution to the issue is to use CSS to superimpose one div element on another through the use of a pseudo image. Pseudo images can be created using :before or using a standard class followed by :after.

Before and after render content as expected:

.small-tab-bl:before{
        content: '';
        width: 378px;
        height: 178px;
        display: block;
        position: absolute;
        background: #f9fafc;
        top: 1px;
        left: 1px;
        clip-path:
            polygon(
                 0% 0%,
                 100% 0%,
                 100% 100%,
                 7.5% 100%,
                 0% 87%);
        -webkit-clip-path:
            polygon(
                 0% 0%,
                 100% 0%,
                 100% 100%,
                 7.5% 100%,
                 0% 87%)
        -moz-clip-path:
            polygon(
                 0% 0%,
                 100% 0%,
                 100% 100%,
                 7.5% 100%,
                 0% 87%)
        z-index: 1;
    }

    .small-tab{
       position: absolute;
       width: 380px;
       height: 180px;
       background: grey;
       clip-path:
            polygon(
                 0% 0%,
                 100% 0%,
                 100% 100%,
                 7.5% 100%,
                 0% 87%);
        -webkit-clip-path:
            polygon(
                 0% 0%,
                 100% 0%,
                 100% 100%,
                 7.5% 100%,
                 0% 87%)
        -moz-clip-path:
            polygon(
                 0% 0%,
                 100% 0%,
                 100% 100%,
                 7.5% 100%,
                 0% 87%)
       z-index: -1;
}

This class clips a div element to create a tab missing the bottom right corner. Two tabs are generated, one positions a single pixel off of the other to create a border. Before must include the gradient and content should be provided.

Conclusion

Before and after are useful tools for placing content and alleviating the problems with clip path.

Differences in Tablets and Browsers Over the Last Few Generations

We all have to do this at some point, create an all encompassing, GUI program that works between the different generations of IPad and even up to 1920 x insane. Increasingly, as of 2018, it doesn’t seem to matter whether you are working in the back or front end, at some point you are creating some sort of front end. Making matters more complicated, a slew of useful and enticing features are starting to become available.

This article is geared towards examining the increasing scale of screen widths in tablets and the differences in available features over time.

Features

Browser features have increasingly grown more powerful. Just a few newer features are:

The links above lead to the MDN pages including browser support. In general, Microsoft Edge or Explorer nearly never supports modern features. However, Microsoft’s browser usage is dropping steadily with Edge taking less than 3 percent of the market and Explorer taking less than 10 percent.

Solid, responsive web applications can be built for Opera, Safari, Chrome, and Firefox without entirely alienating all users but with a slightly outmoded design using CSS hacks or even web frameworks through header parsing.

Firefox, Chrome, and Safari continue to lead the pack in terms of support for newer features.

Device Usage

In terms of devices, the variety of tablet brands is growing. This is leading to a growth in the use of Android devices. This will mean that browsers such as Chrome and Firefox will grow increasingly popular.

Apple continues to lose market share while Microsoft is gaining ground. This could be due to the poor practices of Apple in relation to copyrights and development.


Reactive Trend

The overall trend is towards responsive web development. Each page scales to nearly any resolution required with the exception of mobile which requires a separate site.

This trend carries towards features as well. The days of using stateful web design, jumping from page to page, are nearly dead. Each page is practically a

Future development and certainly my own are also abandoning the typical grid system. Divisions can now become polygons. It is possible to draw complex shapes with d3js.

Web Applications in Unexpected Places

Anything and everything is becoming possible. Web applications are achieving the same power as desktop and mobile applications. However, security will still be a concern.

This power includes on the monitoring side of the IOT sphere. With the ability to launch a browser through tools such as QT and PyQT,  web applications will start showing up in unexpected places.

Consequently, web sockets, RTC, MQPP, and XMPP  will likely grow in popularity.


Screen Sizes

Screens have grown in resolution at the low and high end as expected. Since 2012, screen resolutions have grown from 960 x 720 for an IPAD to 1024 x 768 as well as up to 1366 x 768 on desktop, up from 1280 x 800.

A basic website should be safe coding, in 2018 using:

  • 960 x 720: Older Generation IPads
  • 1024 x 768: Newer Generation of IPads and older desktop screens
  • 1280 x 800: For older screens
  • 1366 x 768: The most common resolution of 2018
  • 1920 x 1080: The future most popular resolution

To stay relevant, plan on coding for both Ipad resolutions as low as 960 x 702 and desktop resolutions as high as 1920 x 1080. My own sites split this resolution into 7 different tiers.

Of course, create a mobile site as well at about 420 width.

The tiers I use are:

  • 900 – 999 width
  • 1000 – 1199 width
  • 12000 – 12299 width (some computers have bizarre resolutions in this range)
  • 1300-1399 width
  • 1400-1599 width
  • 1600 – 1799 width
  • 1800+ width

Frameworks

Frameworks have not changed much but have gotten better. Django now supports channels, Spring has been fully coupled with boot for some time, and Flask is becoming more secure.

More interestingly, React has gained ground due to the power it maintains in building responsive applications. This is really nothing new.

Personally, I utilize Django these days with Flask for micro-services. This allows me to  maintain as single stack for both my front and back-end which utilizes Celery,  Thespian, PyTorch, and Python’s other powerful data tools.

 

””