3/14/20

Redirect HTTP to HTTPS with JavaScript

On production environments, most websites are running under Hypertext Transfer Protocol Secure (HTTPS). This is an encrypted channel that is designed to keep the data between a client browser and server secured.  

When deploying a new website or application, we need to ensure that all traffic coming into the application is via the secure protocol (HTTPS). We should note that this is not available by default. For the most part, this is usually, and the preferred approach, a server side and/or domain registrar redirect rule.

In some cases, there are some difficulties which limits using the server side options. This can include limitations on what can be done on the cloud hosting environment or even lack of access to the domain registrar records. For those cases, we can detect the current protocol and redirect the traffic using client-side JavaScript code.  Let us review an approach by looking at this small snippet.

 

if (location.host.indexOf("localhost") < 0 

  && location.protocol.toLowerCase() !== "https:") {

    const url = `https://${location.host}`;

    location.replace(url);

}

 

 

This code snippet uses the location interface to validate the host name and protocol. If the protocol being used is not under a secured channel (HTTPS), it replaces the current location, essentially redirects, to the same host name, but it forces the secured channel.

Location Interface

The location interface is available globally and accessible via JavaScript. When using it, we could either use window.location or just location. It represents the location (URL, internet address) with all the relevant information that is visible on the browser address bar. This includes the host name and protocol information.

Host Name

The host name contains the current address or domain including port number.  We need this information to check that we are not running on localhost which is the case when we are running on development mode. We just want this rule to be enforced on production environments.

Protocol

The protocol indicates if we are using HTTP or HTTPS which is really what we are interested in finding out. We check that property, and If it does not match the secured channel, we compose a new address using the secured protocol and the host information.  Once we have the information, we are ready to execute a redirect.

Location Replace

With the new address information, we use location.replace to essentially redirect to a new location under the HTTPS protocol. It is important to use the replace method because we do not want to save the unsecured visit to our app in the session history. By using replace, we prevent the user from going back to that page via the back button. Now that we have the approach, where do we add this code?

Where to Place the Snippet

The snippet should run at the very start of the application bootstrapping process. Depending on the  application and framework being used (Angular, React, Vue etc.), we could choose to place this on the App.js file, but in most cases, we would prefer not to load our application instance yet and perform the redirect eagerly. For those cases, just include this file as a script reference on the main/index HTML page before loading the application code. Since JavaScript is single-threaded, the snippet executes first and forces the browsers to load the new secured location.

 

<head>    

 <meta http-equiv="Content-Security-Policy" 

        content="upgrade-insecure-requests">

</head>

<body>

    <div id="root"></div>    

    <script src="/js/redirect.js"></script>

    <script src="/js/app-bundle.js"></script>

 </body>

 


Content Security Policy (CSP)

We should also consider that by forcing the secured channel for our application, we should make sure that all the content (images, CSS)  be requested via the secured channel. To make sure this is done, we add the upgrade-insecure-requests policy as a meta tag in our page. This directive is evaluated to prevent the mixed-content warnings or even blocking due to a block-all-mixed-content policy enforce by browsers.

The solution to redirect HTTP to HTTPS from JavaScript is very simple but understanding the security policy implications on why we need to use a secured channel is a bit more complex. When evaluating that we need to redirect the requests, we need to consider other security concerns and validate that the redirect provides the intended results for the overall user experience.

Thanks for reading.

Originally published by ozkary.com

2/22/20

TypeScript TS7016 Could not Find Declaration Implicitly has any type

When building TypeScript modules, we may come across the TS7016 error. This error indicates that the modules being imported has no strongly typed definitions, and we are trying to use them in a project where type declaration is required. This is a more detail description of what this error may look like.

 

error TS7016: Could not find a declaration file for module './ozkary/ozkary.package'. '/ repos/aiengine/src/modules/speech/speech.package.js' implicitly has an 'any' type.

 

To clarify this error, this just really means that we are attempting to use a JavaScript (not well define types) file on a TypeScript (strongly-typed) project which essentially defeats the purpose. Do not panic yet, there are ways to solve this dilemma. Let us review our options.

Allow for Implicit Any Imports (tsconfig.json)

On a TypeScript project, there is a tsconfig.json file which provides all the information on how to compile the project.  The CompilerOptions node contains several configuration entries. By default, the NoImplicitAny settings is set to false, and it may not be visible on your settings.  This setting allows our project to use files and libraries that are purely written with JavaScript.  To override this error, we can add the value and set it to true as shown below:

 

"compilerOptions": {

    "module""commonjs",

    "noImplicitReturns"true,

    "noUnusedLocals"false,

    "outDir""lib",

    "sourceMap"true,

    "strict"true,

    "target""es2017",   

    "noImplicitAny"true

   

 


Use JavaScript Libraries with TS Support

If we are using TypeScript for a project, it is probably because we want to use a strongly-typed language. When this is the case, we need to use libraries that support TypeScript. If a package we are using is causing this error, we need to look at the latest package updates and see if the latest version do have TypeScript support.  If this is not the case, then overriding the behavior on the tscofig.json file is the fallback option.

Ensure the File Extension is TS not JS

This may seem obvious, but this is a common mistake. When adding new files to the TypeScript project, we need to make sure the file extension is TS not JS. This tiny mistake for sure raises the TS7016 error. It is sometime important to observe and take a close look at the file extension when we see this error.

Strongly Typed Classes instead of Function Components

Using TS files extensions is not enough to indicate that our classes are strongly type. We also need to refactor our code to follow the TypeScript standards. This means replacing JavaScript function component declarations with interfaces and classes that declare strongly type data members.

I hope this was helpful and that it can help in resolving this error from your project. Feel free to add more suggestions on resolving this error on the comments sections.

Thanks for reading.

Originally published by ozkary.com

2/8/20

Feature Branching and Pull-Request Strategy with Git, GitHub and VSCode

When a software development team grows, and we have multiple people working in parallel. Or  even if the team is small, but there are multiple feature changes, the source control versions can quickly become unmanageable with code conflicts. A way to solve this problem is to have developers work on different areas/features of the app.  Even though this helps somewhat, there are still potential problems that can be prevented by following a feature branch and pull-request strategy. This strategy helps us prevent typical problems during the software development cycles. To better understand, let us see what this strategy is about.


Code Repository Branches

As part of the Software Development Lifecycle (SDLC), it is a must practice to use source control software which enables us to track the changes on the software. To isolate the code changes between a development and production version, the concept of branches is used. A branch enables us to track code changes during the development phase and later merge them once that code is deployed to production.

This approach provides the flexibility to create patches from production branch while the development branch is still undergoing changes. The same concept is applicable to the development branch when we want to isolate independent feature changes in which some can be completed much sooner than others.

Feature Branches

A feature branch enables us to isolate code changes for each specific feature.  A “feature” can be a change request, enhancement, or defect fix on the application. A feature branch can also be used to create a software patch from a specific version.  These are often referred as a firefight fix.

The idea behind a feature branch is to create changes or building blocks that are isolated and easily tested independently. For this approach to be successful, we must follow a specific process.

Feature Branch Process

When creating feature branches, we need to adhere a process that is easily repeatable.  In the case of feature development, we want to always create a feature branch from the development branch. Once the feature is complete and ready to test, the code is pushed to the remote repo, and a pull-request (PR) is created which enables the team to run code reviews and merge the code back into development.

Once a feature branch has been merged into development, it is important that all other open feature branches continuously merge back with development to minimize the risk of conflicts. This enables a smooth code merge from multiple feature branches back into the source branch.

Feature Branching with Git

Git is a popular source control management tool that operates on a client workspace. This is not to be confused with Server (remote) Repository like GitHub and Team Services (TFS). The purpose of Git is to clone a remote repo locally and make changes that are only reflected on the local workspace.  For the changes to be available to the rest of the team, the changes must be pushed from a local repo to the remote repo.

When using Git and working on Feature branches, we want to follow a serious of steps that enable us to get the latest changes from the development remote branch and then create a feature branch. We can do this by using Git UI client tools. In our case, we want to use GIT CLI from Visual Studio Code. From VS Code, open a terminal window and let us look at the commands we need to get this done.

Note:  First clone a remote repo and ensure there is development branch. These commands can be done from VS Code Terminal.

 

Command

Description

git checkout development

Checkout the dev branch

git pull origin development

Pull most recent from remote repo

git checkout -b f_featureName

Create a feature branch from dev. This is where the changes are done.

 

 

git add -A

Stage all the ongoing changes

git commit -a -m "#id my new changes"

Commit locally all the changes, add comments and possible issue #id

git pull origin development

Pull from development to merge any pending changes from the remote repo

git push origin f_featureName

Push to the remote repo

 

These are the basic set of commands that enable us to create another branch from the development branch. We should notice that for our feature branch we can use a naming convention (f_*) that can easily tell us what the branch is for. Once the branch is created, we can make the code changes and push our new branch to the remote repo.

Note: It is important to continuously merge from development before pushing the changes.

GitHub Pull-Request

After we have pushed to the remote repo, we can now open a pull-request. This is a gated process which signals to the team that a code review and merge should be executed. A PR can be requested from a GitHub project website (branches page) or using GitHub CLI which can be found at this location https://github.com/cli/cli The GitHub CLI is a sorely needed feature that can enable us to easily create PRs from VSC ode terminal.

After a pull request is merged back into the development branch, the feature branch can be safely deleted from both the remote (team - build manager) and local repos (developer).

Summary

Software development is a complex process, and we need to constantly be learning and creating new processes that can increase our productivity by reducing possible downstream problems. The feature branch pull-request strategy is a simple, repeatable, and valuable process of helping teams work with multiple versions of the product and rapidly adapt to changes.

Thanks for reading.

Originally published by ozkary.com

1/25/20

Launch a Software Product - Product Release Lifecycle

To launch a successful software product, we need to learn and identify the different stages and maturity level that a product reaches during the development and quality assurance cycles.  This can be done by adhering to a product release lifecycle and setting gated stages that can signal when to move to the next stage. Let’s take a look at this in more detail.

Product Release Lifecycle

This lifecycle, also often referred as Product Version Stages, is the process to identify key milestones and quality checkpoints/stages during the development of the product which enables a team to move closer to releasing a product.

The process involves several stages that would progressively show increased quality and product maturity. This is achieved by delivering features and/or testable components early and often (agile). This in turns leads to better Quality Assurance (QA) life cycles.  


Pre-Alpha Stage

In this stage, the product core features are made available for initial testing. This can include login, navigation and some core functionality that is testable. At this stage, the product is very immature and full of issues/bugs.  Those issues need to be resolved to reach quality level that can allow the product to unlock the next stage.

Alpha Stage

In the Alpha Stage, extended features are implemented. The quality has increased due to the initial testing. The team can focus on feature testing for the actual product. The testing cycles are more extensive as cross-components and integration points are validated. The goal in this stage is to have a level of features and quality that show what the end-product would be.

Beta Stage

This stage is the true indicator of the level of maturity of the product. This is a technology preview stage. At this stage, there is a feature lock (no more enhancements). The product is made available for user-acceptance testing with an external audience, possible customers, or user group. The goal is to get feedback from the field, identify defects, unknown issues that could put the release at risk. There is also a chance to identify additional enhancements that could make the product better and learn from possible user adoption problems.  This stage can iterate multiple times until a successful Beta enables the product to move to a Release Candidate stage.

Release Candidate (RC) Stage

In this stage, all the user feedback and identified defects have been addressed. The product quality and stability are high (silver quality). This is the Code Complete stage at which point all the features have been tested and validated. The only additional changes would be fixes/showstopper issues. At this stage, a selected set of customers (possible from the Beta group) can start using the product privately with the goal to identify any issues and/or unknown use cases.

Production Release Stage

After a successful Release Candidate stage, the product has golden quality and high stability. This unlocks the Production Release stage. The product is ready for General Availability (GA) and commercialization. This is now a product that can officially be launched into the market.

Product Launch

The product is now on customer’s hands. At this point, the product goes into learning/maintenance mode in which additional issues, change request (CR) and wanted features would arise. Those items are reviewed, and the ones that are approved are processed and deployed as possible patches (defects) or upgrades (CR).

Summary

In additional to understanding software development life cycles, it is very important to understand the product release lifecycle as this enables us to track a product maturity and stability. It is also important to understand that this is on ongoing process in which we need to continuously iterate to make the product better. By following this process and without rushing to Market, the changes for a successful product increases.

Thanks for reading.

Originally published by ozkary.com

1/11/20

React Function Component Monitor State Changes with Context Hooks

When using React components, there are several lifecycle events that enables us to perform some logic on the behavior of the component. For example, we can check when the component was mounted or when a state variable was changed.  In the case of Function Components, there is no support for lifecycle events because these components are stateless.


In some instances, there is a need for a function component to monitor a state change. For those cases, the first thing that comes to mind is to just use a full component instead. However, what if we want to stick with function components?  What if your function components just need to track an application state change and reflect that change? Well for those cases there is a new alternative.

In the latest releases (16.8) of React, we can use Hooks to monitor a state change and render elements dynamically as a result of the state change somewhere in the app. Let us look at that more in detail by learning about Hooks and how they can help.

Hooks

React Hooks were created to resolve several problems across components.  Basically, as state needs to be shared by multiple components, hierarchy dependencies had to be created in the form of render props and high-order component often leading to a somewhat unclear implementation.

With Hooks, we can use stateful logic independently without impacting a component hierarchy. We can track state changes independently in a non-invasive approach to our existent component.

Now that we have some background, let us look at a specific use case and see how Hooks can help us solve the problem. 

Use Case

As a use case, we have a function component that manages an HTML element on the page. When we first build the application, the element was just meant to show a static element. As usual, the application features can change based on user feedback, and we now need to make this element dynamic.  We want to be able to respond to an application state change and render a different behavior. Let us first look at the code to see how this function component looks without any state management.

App Component

 

//index.js

import React, { Component } from 'react';

import { render } from 'react-dom';

import Header from './Header';

import './style.css';

class App extends Component {

  constructor() {

    super();

    this.state = {

      name: 'React Hooks',

      status: 'info'

    };

   

  // simple timer to change state

  const timer1 = setTimeout(()=>{

   clearTimeout(timer1);  

   this.updateStatus();

   }, 2500);

 

  }

 

 updateStatus = () => {   

   const newStatus = this.state.status === "info" 

          ? "success" : "danger";

   this.setState({status:newStatus});

 }

 

  render() {

    return (

      <div>

        <Header name={this.state.name} status={this.state.status}/>

        <section>

          React function components and hooks

        </section>

        <footer>

        <a href="//ozkary.com">Blog Reference ozkary.com</a>

        </footer>

      </div>

    );

  }

}

render(<App />, document.getElementById('root'));


This is the app main component which is associated to the root element. This component imports the header component which handles the rendering of the app title and a status component. Let’s review the code for those components.

Header  and Status Components

 

//header.js

import React from 'react';

import Status from "./Status"

export default ({ name, status }) => 

<header>

<h1>Ozkary -  {name}</h1>

<Status status={status}/>

</header>

 

 

//status.js

import React from 'react';

export default ({status}) => {

return (

<label className={status}> {status}

</label>

);

}

 

 

In addition to rendering the application title, the header component also imports a status component which is responsible for rendering a color-coded status indicator. By looking at the component, we cannot assert how this state changes. This however is not that relevant since for us, we just need to track when the state changes.  

What we should notice is how the status property has been passed from the top container (app) down to the header and status components. This can become unmanageable when we are dealing with multiple levels of components. For a possible better approach, we can look at how Hooks can help us resolve this without using props.

Lifecycle Hooks

For the purpose of this writing, we are looking at the useContext Hook which enables us to use lifecycle methods in a functional component. This is what we need to be able to track a state change and render the new behavior.

For this approach, we first need to use the  React Context API which enables us to create context variables that can be used in other areas of the app using Hooks.  For this to work, we need to create a context provider which allows us to provide the data to other components by wrapping them into a provider markup.  

Context Provider

 

// context.js

import React from 'react'

 

const StatusContext = React.createContext("");

 

// provides the contexr to other components

export const StatusProvider = StatusContext.Provider

 

// use context to hook into the changes

export default StatusContext

 

We are now ready to remove our props dependency from the header and status components, and instead, we can add the status context provider and required mark-up. After updating our code, we can focus only on the areas of change to illustrate how we are importing a new file and adding the StatusProvider tag around the Header component.

Revised App Component

 

 

import {StatusProvider} from "./context";

 

class App extends Component {

 

  render() {

    return (

      <div>

        <StatusProvider value={this.state.status}>

          <Header name={this.state.name}/>

        </StatusProvider>        

        <section>

          React function components and hooks

        </section>

        <footer>

        <a href="//ozkary.com">Blog Reference ozkary.com</a>

        </footer>

      </div>

    );

  }

}

 

On the Header and Status component, we have removed the props dependencies and use the useContext Hook to listen to state changes outside the function component.

 

// header.js

export default ({ name, status }) => 

<header>

<h1>Ozkary -  {name}</h1>

<Status/>

</header>

 

// status.js

import React, { useContext } from 'react';

import StatusContext from "./context"

 

export default () => {

   const contextStatus = useContext(StatusContext);

 

return (

<label className={contextStatus}> {contextStatus}

</label>

);

}

 

With our revision, we are no longer nesting all these props downstream to all other components. There is however the limitation that we need to introduce the provider element into the view to allow us to hook the context changes downstream to the other functional components. 

Conclusion

When we find ourselves having to pass down the props to multiple levels of stateless components, we may want to look at using context and Hooks to prevent this approach and just receive data change events.

Thanks for reading.

Originally published by ozkary.com