Monthly Archives: July 2018

Why 'This' in JavaScript

By William Imoh

While JavaScript is a fun and powerful language, it can be tricky and requires a proper understanding of its underlying principles to mitigate common errors.

In this post, we shall be introducing you to the this keyword, its behaviour and the hard choices behind it. These will be detailed using appropriate examples to better drive home the point.

What is this?

Developers make the mistake of thinking that this refers to the “scope” of the function within which it’s encountered. This isn’t true because whenever a function is invoked, it runs in a new execution context until its execution is completed. Each execution context usually references an object and the value of that object translates to the value of this.

For us to properly understand what this is, we would first need to go over two important concepts:

  • Context
  • Call-Site

Context

Commonly in the English language, once a noun is defined in a sentence, subsequent references to the subject noun will be done using a pronoun. Understand?

First Statement: Brad is a good boy.
Second Statement: He is a very brilliant boy!

Who is a brilliant boy? Brad… obviously!

This is quite the same in JavaScript, the first statement creates the context, while this functions like ‘he’ in the second statement and is used to reference the subject in the first statement.

this refers to the context of an executing function.

This would mean that during every function execution, the focus is on the new execution context which is redetermined whenever a function is invoked, and since the context holds a reference to an object, the value of this is updated accordingly.

It is impractical to assume that the value of this is fixed and always refers to the function’s scope, the value of this is, in fact, dynamic and determined by how a function is called and where it is called:

Different sections in a JavaScript program run in an execution context and maintain that context until there is a switch to a new context. The context of an executing function references the object that invoked it, therefore, a call to this within a function refers to the invoking object.

Since the context is really important to our understanding of this, we need to know how/why the context switches during runtime:

How does the context change?

The current execution context in a JavaScript program usually points to the object that invokes a function and can be switched to another object by invoking the function with another object.

Call-Site

The place where a function is invoked in a JavaScript program is called the call-site. This is also important in determining the value of this because if the function isn’t invoked by any visible object, the current context of the call-site would be responsible for setting the new execution context of the function.

In simpler terms, the value of this represents the context of the initial executing function in a call-site and remains the same in any other call-site an invoking function doesn’t provide context.

We can finally define this based on all of the explanations presented above:

The value of the this keyword is dependent on the object upon which it is invoked and not the function itself or the function’s scope.

The call-site of the function is also important in determining what this refers to.

This bindings

There are four bindings that are important in determining the value of this in a JavaScript program. We will look at them in this section.

Default binding

Let’s say we were writing a program and defined a function where we used the this keyword, then we invoked the function in the global scope (outside of any function) of the program. What object do you think the this keyword would reference runtime? Let’s see:

let randomFunction = () => {
  this.attribute = 'This is a new attribute to be created on the invoking object';
  console.log(this);
}

randomFunction();

Good thinking! This references the global object in the output below:

In the code above, we created a random function that attaches a new property “attribute” to whichever object invokes it. Because the call-site of the function invocation had its context referencing the global object (this is default), we see that in the output, the console logs a lot of properties that are attached to the global object (Window object) including the property that was created by the random function.

This is the default binding of this in JavaScript. When a function is called without an object, this is by default bound to the current execution context, we will look at the other bindings below.

By default, this is bound to the global object when invoked by a global function.

It is noteworthy that when we are coding in strict mode, this holds the value of undefined in global functions and in anonymous functions that are not bound to any object.

Explicit Binding

Remember how we said that the execution context can be changed by invoking a function on an object? Well, there are explicit ways to easily achieve the same result, let’s look at them briefly:

  • Bind: This method creates a new function and when invoked sets its ‘this’ keyword to a provided value (passed as an argument).
  • Call – This method calls a function and allows us to specify the context its this value should be bound to as an argument. This method accepts optional arguments.
  • Apply – This function is similar to call() with a difference of allowing us to pass in arguments as an array.

Let’s look at an example:

let randomFunction = () => {
  console.log(this);
}

let newObj = {
  description : "This is a new Object"
}

console.log(randomFunction.bind(newObj)());
console.log(randomFunction.call(newObj));
console.log(randomFunction.apply(newObj));

In the code above, we have explicitly bound this in the random function to the newObj variable and we can see that the call, bind and apply methods are available on the Function prototype in JavaScript. They are all correctly bound in the output below:

Implicit Binding

When an object defines a method (that calls this) as a property and calls that method somewhere in a program, the this within the method will be implicitly bound to that object. Let’s look at this example:

let newObj = {
  description : "This is a new Object",
  randomFunction(){
  console.log(this);
  }
}

newObj.randomFunction();

This is a straightforward example that complies with our definition of this above; the invoking object is implicitly bound to the method here and it logs the object when invoked:

New Binding

If we have an object constructor and create a new object with it, the new object will have its this value as a reference to the constructor from which it was created. This is the this binding that happens when a new object is created using a constructor. Let’s look at an example:

function newObj() {
  this.description = "This is an object constructor"

  this.randomFunction = () => {
  console.log(this);
  }  
}

let anotherFunction = new newObj()
anotherFunction.randomFunction()

In the snippet above, we defined a new constructor function and gave it description and randomFunction property and method respectively. We created an instance with the anotherFunction variable and invoked its randomFunction method, here’s the output:

Here, the logged object has the description property that was defined on the object constructor to prove that this references the constructor function.

This and That

The takeaway from everything that has been shown above is:

Wherever this is defined in a function, it usually isn’t assigned a value until an object invokes the containing function.

You might think that the paragraph above is all you would ever need to refer to when you work with this but there are scenarios where this behaves in a weird way (cus JavaScript).

Let’s look at a code snippet where we define a closure that references this in JavaScript:

let newObj = {
  description : "This is a new Object",

  randomFunction(){
    let a = 1

    return function() {
      console.log(this);
    }
  }
}

newObj.randomFunction()();

You would reasonably expect that the closure returns the value of this as the object that invoked randomFunction but let’s see what the output says:

Wait, what? How does this refer to the global object here?
Wasn’t the outer function called by the newObj object?
Shouldn’t that have switched the execution context and updated the this reference?

These are all valid questions, however, here’s something to note:

Closures cannot access their outer function’s this value by calling this within themselves.

This is because the this value of a function is only accessible by the function within which it is encountered and not its inner functions. Hence the this of an anonymous closure will be bound to the global object where strict mode is not being used.

How can we get the preferred behavior?

Here’s a trick. Consider this code snippet:

var newObj = {
  description : "This is a new Object",
  randomFunction(){
    var that = this;

    return function() {
      console.log(that);
    }
  }
}

newObj.randomFunction()();

Here, in randomFunction we declare a new variable called that and assign it the value of this. This way, we can reference the this value of the outer function within the closure since the scope of an outer function is always accessible by its inner functions.

Here’s the output:

Great! We have referenced the this value of the outer function in the closure by creating a that variable.

It should be noted that we could have called the variable anything at all but chose that because so many JavaScript developers already find it convenient to call it that. I sometimes choose cat or thanos hehe.

Now you know this… and that.

Conclusion

We have explored the this keyword in JavaScript clarifying its behavior and use in the process. We also looked at the scenario of closures where the this logic may be elusive and we went over a fitting solution, however, there are situations where this can still prove tricky, the best way to figure it out is to identify which of the bindings is in operation during the function execution and trace back the context carefully. Feel free to leave your feedback and comments. Happy coding!!

Source:: scotch.io

The Node.js Update - #Week 28 - 13 July, 2018

By Tamas Kadlecsik

The Node.js Update - #Week 28 - 13 July, 2018

Below you can find RisingStack‘s collection of the most important Node.js news, updates & tutorials from this week:

Postmortem for Malicious Packages Published on July 12th, 2018

On July 12th, 2018, an attacker compromised the npm account of an ESLint maintainer and published malicious versions of the eslint-scope and eslint-config-eslint packages to the npm registry. On installation, the malicious packages downloaded and executed code from pastebin.com which sent the contents of the user’s .npmrc file to the attacker. An .npmrc file typically contains access tokens for publishing to npm.

We, the ESLint team, are sorry for allowing this to happen. We hope that other package maintainers can learn from our mistakes and improve the security of the whole npm ecosystem.

The malicious package versions are eslint-scope@3.7.2 and eslint-config-eslint@5.0.2, both of which have been unpublished from npm. The pastebin.com paste linked in these packages has also been taken down.

Testing Node.js in 2018

Setting up a good test framework can be tricky regardless of what language you’re using. In this post, we’ll uncover the hard parts of testing with Node.js, the various tooling we decided to utilize in Winds 2.0, and point you in the right direction for when it comes time for you to write your next set of tests.

Node.js REPL in Depth

REPL stands for read-eval-print-loop, or just an interactive session (usually in your terminal), where you can enter some expression and immediately evaluate it, seeing the result. After evaluating, the whole flow repeats, and it works until you exit the process. So, R stands for reading your command, E stands for evaluating it, P stands for printing the result of the execution, and L means to run the whole process again, “in the loop”.

Build and Understand a Simple Node.js Website with User Authentication

Building websites with user authentication and management (login, registration, password reset, etc.), can be a huge pain. As a developer there are a million little things you need to worry about:

  • Storing the users in your database
  • Making sure you have the right user attributes defined
  • Forcing users to be logged in to view a page
  • Building registration and login forms
  • Creating password reset workflows that email users a link
  • Verifying new users when they sign up via email
  • Etc…

Building a Node JS interactive CLI

Node.js can be very useful when it comes to building Command-line Interfaces also known as CLI’s. This post teaches you how to build a CLI that asks some questions and creates a file, based on the answers.

How I built a job scraping web app using Node.js

Indreed is a Rest API for scraping jobs from Indeed and around the web. It is powered by my personal web scraping project and layered on a rest API. Its a real Rest API and can be used from any platform using any programming language.

npm Joins ECMA International and TC39

We’re excited to announce that npm has joined ECMA International and is participating in TC39, the working group of ECMA International that defines the standard for the JavaScript programming language. (The standard is, strictly speaking, called ECMAScript, although everyone refers to it as JavaScript.)

Node.js is Viriciti’s Go-to Dev Platform for Real-time Electric Vehicle Fleet Monitoring

Viriciti, a company focused on electric vehicle fleet monitoring, orchestrates hundreds of thousands of messages per second into real-time dashboards using Node.js, microservices, and serverless. They use Express Gateway, an open source API gateway built on Express.js, to make data available through their API tier.

signale – a hackable console logger for Node.js apps

Hackable and configurable to the core, signale can be used for logging purposes, status reporting, as well as for handling the output rendering process of other node modules and applications.

Previous Node.js Updates:

From the previous Weekly Node.js Update:

  • Node v10.6.0 (Current) Released. Update now!
  • Multi-server Chat in Node Without a Database
  • The Art of Node: An introduction to Node.js
  • Case Study: How Bustle uses Node.js to Speed Up App Development

& more…

We help you to stay up-to-date with Node.js on a daily basis too. Check out our Node.js news page and its Twitter feed!

Source:: risingstack.com

Code Challenge #12: JavaScript String Manipulation

By William Imoh

Last time on the Code Challenge #11 we solved problems in JavaScript using functions to manipulate objects.

This week on the code challenge we shall delve further into the important basics with String Manipulation challenges.

Strings in JavaScript are data types containing characters in single or double quotes.

Manipulating Strings are an integral part of app development and is applied in numerous cases from modifying user input data to making UX and UI decisions on a page depending on specific user inputs.

The Challenge

In this challenge, we’ll be solving five problems with possibly increased difficulty from first to last.
The five problems are:

Padded Number

In this challenge, an array is provided and stored in a variable, create a function which evaluates the strings in the array by adding a preceding 0 to single numbers (6 => 06, 5 => 05). Double figures remain as is.

Camel-to-Title

Convert a given sentence from camel case to title case. Create a function which evaluates a given sentence argument in camel case and converts it to title case.

Title-to-Camel

This the opposite of the last challenge, create a function which receives a string in title case as an argument and returns a converted version in camel case. Convert the given variable into a sentence with pairs of words in camel case. In cases where the word count is odd, leave the last word standing singularly.

Passage Counter

This is a feature utilized by most blogs to calculate reading time. Create a function which calculates the time to read a text in seconds, if it takes over 60 seconds to read a passage return the time to minutes.

Pig Latin

Quite an interesting challenge, convert any given word to Pig Latin. Create a function which receives an argument of a string and subsequently returns the Pig Latin version of it. Here’s how to convert words to Pig Latin:

  • In words that begin with consonant sounds, all letters before the initial vowel are placed at the end of the word sequence. Then, “ay” is added.
  • When words begin with consonant clusters (multiple consonants that form one sound), the whole consonants before the vowel is added at the end followed by an “ay”.
  • In words that begin with vowel sounds, one just adds “ay” to the end.

See more about Pig Latin here on Wikipedia.

Note that you can write your results to the DOM or even log to console, whichever is fine by you.

Requirement

Feel free to utilize any method, technique, tool or technology to complete this challenge. A key requirement of these challenges is to be able to correctly evaluate the conditions of the challenge by passing a value as an argument, to the created function.

Goals for the Challenge

On completion of this challenge, you should be able to:

  • Solve simple algorithms by manipulating String values.
  • Understand the usage of JavaScript methods to manipulate String values.

Bonus

As a bonus for this challenge, write all functions using ES6 syntax. This should be hella fun!!

Resources

In order to get started quickly with this challenge, a base codepen is provided containing empty function definitions. Sample variables with which you can test your functions are also provided. Also, find instructions for each individual challenge in the pen.

Fork this base codepen to get started.

Community

On completion of the challenge, you can showcase your work to receive reviews. Here’s how:

  • Post it on Twitter using the hashtag #scotchchallenge and be sure to tag us to see it!
  • Build your writing skills by writing about how you solved it and we’ll be glad to feature it in our community posts!
  • Post it in the comment section under this post.
  • Join the chatter on Spectrum and showcase your solution.

Join the conversation, meet awesome developers, ask questions, discuss awesome topics and leave your feedback in the Scotch Spectrum Forum.

Solution

The solution to the post will be released on Friday. Happy coding!!

Source:: scotch.io

Build and Understand a Simple Node.js Website with User Authentication

By rdegges

using the site

Building websites with user authentication and management (login, registration, password reset, etc.), can be a huge pain. As a developer there are a million little things you need to worry about:

  • Storing the users in your database
  • Making sure you have the right user attributes defined
  • Forcing users to be logged in to view a page
  • Building registration and login forms
  • Creating password reset workflows that email users a link
  • Verifying new users when they sign up via email
  • Etc…

The list goes on and on.

Today I’m not only going to show you how to quickly build a Node.js website that supports all those things above, I’m going to teach you exactly what’s going on behind the scenes so you fully understand how web authentication works.

If you’ve ever been curious about how web authentication and user security works, you will enjoy this. =)

What We’re Building

As I mentioned above, today we’ll be building a simple Node.js site that supports a few key user flows:

  • User registration
  • User login
  • Password reset
  • Email verification

The end product of this article looks like this:

If you want to see a preview of this project live, you can do so here: https://okta-express-login-portal.herokuapp.com/.

The site will be built using a few different tools (you don’t need to know them already):

  • Express.js, the most popular web framework in the Node.js ecosystem.
  • express-session, a popular session management library. This is what will allow us to create and store cookies that remember who a user is.
  • Pug, a popular templating language that makes writing HTML a bit simpler.
  • oidc-middleware, a popular developer library that makes handling authentication using the OpenID Connect protocol simple

Install the Tools

The first thing you need to do is install all the open source tools we’ll be using to build this Node.js site.

PS: If you don’t already have Node.js setup and working on your computer, you can go checkout this link which shows you the best way to get it working regardless of what operating system you’re using.

Next, install the express-generator tool, which is the officially supported bootstrapping tool for quickly getting started with Express.js.

npm install express-generator@4.16.0

Once that’s done, you’ll want to scaffold your new Express.js site using express-generator.

express --view pug login-portal
cd login-portal
npm install

You now have a simple Express.js website that you can run and test out. Start up your new web server by running npm start then go visit http://localhost:3000 in your browser to make sure everything is working OK. If all is well, you should see a page like the one below.

express starter page

Next, install some additional packages. We’ll use these packages through the rest of the tutorial. Getting them installed and out of the way upfront will make it simpler later on.

To install all the extra dependencies, run the following commands in your terminal.

npm install express-session@1.15.6
npm install @okta/oidc-middleware@0.1.3
npm install @okta/okta-sdk-nodejs@1.1.0

Now, on with the show!

Setup Your Authorization Server

Historically, implementing web authentication has been a bit of a mess. Everyone used to implement authentication patterns in different, arbitrary ways. Over the last few years, however, the game has changed quite a bit with the introduction and growing popularity of the OpenID Connect protocol. If you want to read up on OpenID Connect, I recommend [this series]](https://developer.okta.com/blog/2017/07/25/oidc-primer-part-1).

One of the core tenants of OpenID Connect is the authorization server. An authorization server is a one-stop shop that handles all of the user login flows for your applications. The idea is that your application redirects to the authorization server to process user logins and the authorization server then redirects the user back to your website once the user has been authenticated.

Authorization servers make handling user management a significantly simpler, less risky task — so that’s what we’ll be doing today: using an authorization server provider (Okta) to make the process simple and secure.

Okta is free to use and allows you to create and manage users, authorization servers, and lots of other tasks that make handling web authentication simple.

To get started with the authorization server setup, you first need to go create a free Okta developer account: https://developer.okta.com/signup/. Once you’ve created your account and logged in, follow the steps below configure Okta and then you’ll be ready to write some code!

okta signup

Step 1: Store Your Org URL

The first thing you need to do is copy down the Org URL from the top-right portion of your Okta dashboard page. This URL will be used to route to your authorization server, communicate with it, and much more. You’ll need this value later, so don’t forget it.

okta org url

Step 2: Create an OpenID Connect Application

Okta allows you to store and manage users for multiple applications you might be creating. This means that before we can go any further, you need to create a new OpenID Connect application for this project.

Applications in OpenID Connect have a username and password (referred to as a client ID and client secret) that allow your authorization server to recognize which application is talking to it at any given time.

To create a new application browse to the Applications tab and click Add Application.

okta add application

Next, click the Web platform option (since this project is a web app).

okta create web app

On the settings page, enter the following values:

  • Name: login-portal
  • Base URIs: http://localhost:3000
  • Login redirect URIs: http://localhost:3000/users/callback

You can leave all the other values unchanged.

okta create app settings

Now that your application has been created, copy down the Client ID and Client secret values on the following page, you’ll need them later when we start writing code.

okta app credentials

Step 3: Create an Authentication Token

In order to access the Okta APIs and be able to manage your user accounts with a great deal of granularity, you’ll also need to create an Okta authentication token. This is an API key that will be used later on communicate with the Okta APIs and allows you to do things like:

  • Create, update, and delete users
  • Create, update, and delete groups
  • Manage application settings
  • Etc.

To create an authentication token click the API tab at the top of the page followed by the Create Token button. Give your token a name, preferably the same name as your application, then click Create Token. Once your token has been created, copy down the token value as you will need it later.

okta create token

Step 4: Enable User Registration

The last piece of setup you need to complete is to enable user registration functionality for the authorization server. Normally, authorization servers only support login, logout, and stuff like that. But Okta’s authorization server also supports self-service registration, so that users can create accounts, log into them, reset passwords, and basically do everything without you writing any code for it.

In your Okta dashboard, you’ll notice a small button labeled Developer Console at the top-left of your page. Hover over that button and select the Classic UI menu option that appears.

okta switch console

Next, hover over the Directory tab at the top of the page then select the Self-Service Registration menu item. On this page click the Enable Registration button.

okta enable registration

On the configuration page, leave all the settings as their default values, except for the Default redirect option. For this option, click the Custom URL radiobox and enter http://localhost:3000/dashboard as the value.

This setting essentially tells the authorization server where to redirect users after they’ve successfully created a new account on your site.

Once you’ve clicked Save, the last thing you need to is switch back to the developer console.

okta registration settings

Hover over the Classic UI button at the top right of the page and select the Developer Console menu item from the dropdown.

Configure Session Management

Now that all the setup work is done, let’s write some code!

The first thing we’ll add to this basic Express.js site is support for sessions using the express-session library.

Session management is the core of any authentication system. It’s what allows a user to stay logged into your site and not have to re-enter their credentials before viewing each page. The most secure way to handle user sessions is via server-side cookies, which is why we’ll be using the express-session library: it allows us to create and manage server-side cookies.

To start, open up the ./app.js file in your favorite editor (I prefer neovim), and import the session library at the top of the file alongside the other import statements. The app.js file is the heart of your Express.js site. It initializes the Express.js web server, contains the site settings, etc.

var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
var session = require("express-session");

Next, you need to remove the cookie-parser library that express-generator included by default, since we won’t be using it. In the ./app.js file delete the following two lines of code.

var cookieParser = require('cookie-parser');

// and…

app.use(cookieParser());

Now all you need to do is plug the express-session library into the ./app.js file along with the other middlewares.

app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use(session({
  secret: 'LONG_RANDOM_STRING_HERE',
  resave: true,
  saveUninitialized: false
}));

Make sure to replace LONG_RANDOM_STRING_HERE with an actual random string you type. This string is what will keep your user’s cookies safe from compromise. I personally like to bash my hands around on the keyboard for a second to generate something random.

programming

This session library handles a lot of work behind the scenes:

  • It creates secure, cryptographically signed cookies so you can store data in a user’s browser. Cryptographic signing is a technique that allows your server to tell whether or not a user has tried to “modify” their cookies to make it look as if they’re someone they’re not.
  • It gives you a simple API for creating and removing cookies
  • It allows you to tweak and configure cookie settings based on what you need to do

As you’ll see in a moment, this library is used by the oidc-middleware library behind the scenes to make user authentication magical.

Create Express.js Views

The next thing we’re going to do is create our Express.js views. Views in Express.js are nothing more than HTML templates (web pages) that we want to display to a user. But unlike normal HTML, we’ll be using the Pug templating language to create our views.

Pug is one of the most popular templating languages in the Node.js ecosystem because it allows you more concisely write HTML, use variables, and things like that.

Create the Layout View

The first (and most important!) view we’re going to create is the ./views/layout.pug view. This is the “base” view that all our other views will extend.

In this view we’ll define the basic layout of all the pages, the navbar, and stuff like that. Open up the ./views/layout.pug and replace whatever is in the file with the following.

block variables

doctype html
html(lang="en")
  head
    meta(charset="utf-8")
    meta(name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no")
    link(rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous")
    link(rel="stylesheet", href="/stylesheets/style.css")
    title okta-express-login-portal: #{title}
  body
    div.top-bar.d-flex.flex-column.flex-md-row.align-items-center.p-3.px-md-4.mb-3.bg-white.border-bottom.box-shadow
      h5.my-0.mr-md-auto.font-weight-normal
        a(href="/", title="Expresso") okta-express-login-portal
      nav.my-2.my-md-0.mr-md-3
        a.p-2.text-dark(href="/", title="Home") Home

        if user == undefined
          a.p-2.text-dark(href="/users/login") Log In / Register
        else
          a.p-2.text-dark(href="/dashboard") Dashboard
          a.p-2.text-dark(href="/users/logout") Logout
    .container
      block content

    footer.
      Built with #[a(href="https://expressjs.com/") Express.js], login powered by #[a(href="https://developer.okta.com/") Okta].

As you can probably figure out if you’re at all familiar with HTML, pug is very similar to HTML but uses whitespace instead of closing tags (like the Python programming language).

This layout view doesn’t do anything except render a simple page with a navbar at the top, a footer at the bottom, and two special constructs, block variables and block content.

The block variables line at the top of the file means that any of the templates that inherit from this one will be able to inject some variables into the page. You might have noticed that the title tag contains a variable: #{title} — this is one of the variables that a child template can overwrite later on.

Did you notice the block content line right above the footer? This block allows a child template to inject HTML into our layout template at just the right spot — this way our child templates don’t need to re-define a navbar, page header, etc.

By using these two blocks: variables and content, our child templates can build full web pages with nothing more than a title and some body content. Pretty nifty.

Create the Homepage View

The next view we’ll create is the ./views/index.pug view. Open that file and insert the following code.

extends layout

block variables
  - var title = "Home"

block content
  h2.text-center Express App

  .row
    .offset-sm-2.col-sm-8
      .jumbotron.text-center.
        Welcome to your new Express app! Please visit the
        #[a(href="https://github.com/rdegges/okta-express-login-portal", title="okkta-express-login-portal on GitHub") GitHub page] to learn more.

Notice the extends layout line at the top. This is what tells pug that this template is a child of the layout template we created earlier.

In the block variables section we then define our title variable which will be used in the layout template to output the page title, and in the block content section we insert the HTML for the rest of the page.

As you can hopefully see by now, template inheritance in Pug is pretty straightforward.

Create the Dashboard View

The next view to create is the dashboard view. This is the page users will see once they’ve logged into the site. Open up the ./views/dashboard.pug file and insert the following code.

extends layout

block variables
  - var title = "Dashboard"

block content
  h2.text-center Dashboard

  .row
    .offset-sm-2.col-sm-8
      .jumbotron.text-center.
        Welcome to your dashboard page, #{user.profile.firstName}.

You’ll notice that in this template there’s a new variable being used: #{user}. This will eventually refer to the currently logged in user as you’ll see later on.

Create the Error Views

The last two views you need to create are for handling errors.

Open up the ./views/error.pug view and insert the following code.

extends layout

block content
  h1= message
  h2= error.status
  pre #{error.stack}

This view will be rendered when the user hits a URL that doesn’t exist (404), or when the web server has a problem (5XX).

You’ll also need to create a file named ./views/unauthenticated.pug and insert the following code. This view will be displayed to a user if they visit a page that requires them to be logged in.

extends layout

block variables
  - var title = "Unauthenticated"

block content
  h2.text-center You Must Log In to View This Page
  p.text-center.
    You must be signed in to view this page. Please #[a(href="/users/login", title="Login") login or register] to view this page.

Create Public Routes

Routes in Express.js are the place where you define application logic. They dictate what code runs when a particular URL is hit by a user, and what response is sent back.

To get started, let’s remove the default routes that express-generator created for you. Run the following command to remove them.

rm routes/*

Next, create a file named ./routes/public.js and insert the following code.

const express = require("express");

const router = express.Router();

// Home page
router.get("/", (req, res) => {
  res.render("index");
});

module.exports = router;

In this module we’re creating a new Express.js Router and telling it that if a user makes a GET request to the / URL, then we’re going to run a function that renders the index.pug view file we created earlier and returns it to the user.

Now this won’t take effect just yet (for reasons you’ll learn about later on), but once this router is “enabled”, every time a user makes a request for the homepage of the site, eg: http://localhost:3000, this code will run and the index.pug view will be shown.

Pretty neat, right?

Next, create a file named ./routes/dashboard.js and insert the following code.

const express = require("express");

const router = express.Router();

// Display the dashboard page
router.get("/", (req, res) => {
  res.render("dashboard");
});

module.exports = router;

This router acts similarly to the homepage router above, except it is rendering our dashboard page. While it doesn’t make sense just yet, if a user eventually visits the /dashboard URL, this function will run which will render the dashboard.pug defined earlier.

If you were to go into this file and define another route, for example:

router.get("/test", (req, res) => {
  res.render("test");
});

… You would find that a user would need to visit /dashboard/test to trigger the function to run. Again: don’t worry about this not adding up just yet, we’ll get to that down below.

Enable the Routes

Now that you’ve created some routes for public pages, let’s enable them with Express.js so we can actually see them in action!

To do this, open up the ./app.js file and delete the following two lines.

var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');

Replace those two lines with the two lines of code below.

const dashboardRouter = require("./routes/dashboard");         
const publicRouter = require("./routes/public");

Now we’re importing the correct route files we just defined above.

Next, scroll down until you see the following two lines of code and delete them.

app.use('/', indexRouter);
app.use('/users', usersRouter);

Those lines of code were loading up the old routes we just deleted. Now you need to change those lines of code to look like this.

app.use('/', publicRouter);
app.use('/dashboard', dashboardRouter);

Is it starting to make sense now? These app.use lines of code tell Express.js that if a user visits the / URL, it should look into the ./routes/public.js file and start matching URLs there to run against. So if a user visits the homepage, eg: /, Express.js will look in the ./routes/public.js file, find the route that serves the / URL, then run the associated function.

The same thing happens with the dashboardRouter below. If a user visits /dashboard, then Express.js will look in the ./routes/dashboard.js file for a function that runs when the / URL is called, because /dashboard + / is the path the user is visiting!

Routes in Express.js make it easy to compose complex sites with lots of nested URLs without a lot of work.

Now that you’ve enabled your routes, go test them out. Start your web server by running the command below.

npm start

Then visit http://localhost:3000 in your browser. You should see the following page rendered.

app unstyled

NOTE: This page doesn’t look just right yet because we haven’t created any CSS yet. We’ll do that last.

If you now go visit the dashboard page you created, http://localhost:3000/dashboard, you’ll notice you get an error. That is because that Pug view refers to the #{user} variable we haven’t yet defined. We’ll get to that soon.

Configure User Authentication

Now that our Express.js site is starting to become functional, let’s dive deeper into user authentication.

The first thing you need to do is open up ./app.js and import the following two libraries at the top of the file.

var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
var session = require('express-session');
var okta = require("@okta/okta-sdk-nodejs");
var ExpressOIDC = require("@okta/oidc-middleware").ExpressOIDC;

The two libraries we just added are at the bottom of the list: @okta/okta-sdk-nodejs and @okta/oidc-middleware. These two libraries handle all of the OpenID Connect communication and routing.

The next thing we need to do is create an oktaClient object as well as an ExpressOIDC object. These will be used in a moment once we’ve configured them and given them the right credentials.

To do this, open up your ./app.js file again, find the line that reads var app = express();, and insert the following code immediately beneath it.

var oktaClient = new okta.Client({
  orgUrl: '{yourOktaOrgUrl}',
  token: '{yourOktaToken}'
});
const oidc = new ExpressOIDC({
  issuer: "{yourOktaOrgUrl}/oauth2/default",
  client_id: {yourClientId},
  client_secret: {yourClientSecret},
  redirect_uri: 'http://localhost:3000/users/callback',
  scope: "openid profile",
  routes: {
    login: {
      path: "/users/login"
    },
    callback: {
      path: "/users/callback",
      defaultRedirect: "/dashboard"
    }
  }
});

Now, remember those values I told you to write down way back at the beginning of this post? Now you need them! Make sure you substitute out the following variables above for the proper values: {yourOktaOrgUrl}, {yourOktaToken}, {yourClientId}, and {yourClientSecret}.

The oidc object created handles 100% of the OpenID Connect protocol support. It handles router the users to the authorization server to handle user registration, login, password reset, etc. It handles logging the users into your application using secure cookies (powered by express-session), and it also handles everything else.

The oktaClient object is merely used to retrieve user data from the Okta API service.

Now that our OpenID Connect support is ready to be used, let’s enable it. To do this, open up the ./app.js and find the session middleware from earlier, then add the following line beneath it.

app.use(session({
  secret: 'asdf;lkjh3lkjh235l23h5l235kjh',
  resave: true,
  saveUninitialized: false
}));
app.use(oidc.router);

The app.use(oidc.router); call is all that’s needed to tell Express.js to enable the routes that ship with the oidc-middleware library to handle all of the OpenID Connect support. You might have noticed above that when we created the oidc object we specified some routes in the configuration. These settings dictate what URLs we want to use to handle user login, and what URLs we want to redirect users to after they’ve been logged in.

One benefit of this router being enabled is that from this point forward, in any of our route code, we’ll have access to a special variable, req.userinfo, which contains some of the currently logged in user’s basic profile information (pulled from Okta).

And while req.userinfo is nice, it’d be a lot nicer if we could get any data about the currently logged in user that we want.

So let’s go ahead and define another middleware to help us with that. Immediately below the app.use(oidc.router); code, insert the following:

app.use((req, res, next) => {
  if (!req.userinfo) {
    return next();
  }

  oktaClient.getUser(req.userinfo.sub)
    .then(user => {
      req.user = user;
      res.locals.user = user;
      next();
    }).catch(err => {
      next(err);
    });
});

This middleware will run on every user request, and does the following:

  • It checks to see if there is a currently logged in user or not by looking at the req.userinfo object. If there is no user logged in, it will do nothing (return next();).
  • If there IS a user logged in, this middleware will then use the Okta Node SDK library to retrieve the user object from the Okta API.
  • Finally, it will create two new values: req.user and res.locals.user which point to the user object directly.

This means that in any route we define later on, we could access the req.user object directly to view the user’s information, edit it, or even delete it.

For example, you could create the following route below to display the user’s profile information each time a user visits the /test URL:

app.get('/test', (req, res) => {
  res.json({ profile: req.user ? req.user.profile : null });
});

Let’s also go ahead and create one additional middleware, loginRequired, that will only allow a user to visit a route if they’ve been logged in already. This will come in handy if you want to build pages that only logged in users can access (a dashboard, etc.).

Below the code above, go ahead and define the function below.

function loginRequired(req, res, next) {
  if (!req.user) {
    return res.status(401).render("unauthenticated");
  }

  next();
}

Since we want to ensure only logged in users can view our dashboard page, let’s also go back and modify our route code for the dashboard.

Find the line of code that enabled the dashboard route in your ./app.js.

app.use('/dashboard', dashboardRouter);                        

Now modify it to look like this.

app.use('/dashboard', loginRequired, dashboardRouter);

By injecting the loginRequired function immediately after the URL pattern, Express.js will first run our loginRequired middleware BEFORE the dashboardRouter is processed. This way, if a user visits any page that starts with the URL /dashboard they’ll be required to log in before they can access it!

The final thing we need to do to finish up our authentication component is define a logout route. The oidc-middleware library provides logout functionality, but doesn’t automatically generate a route for it.

To do this, create a new file named ./routes/users.js and put the following code inside of it.

const express = require("express");

const router = express.Router();

// Log a user out
router.get("/logout", (req, res) => {
  req.logout();
  res.redirect("/");
});

module.exports = router;

As you can probably tell, this route will log a user out of their account if they send a POST request to the /users/logout URL. The only thing we need to do now is enable this route in our ./app.js.

Open up ./app.js, and import this new route file alongside the others at the top of the file.

const dashboardRouter = require("./routes/dashboard");
const publicRouter = require("./routes/public");
const usersRouter = require("./routes/users");

Next, scroll down until you see your other routers being enabled, and enable this router as well.

app.use('/', publicRouter);
app.use('/dashboard', loginRequired, dashboardRouter);
app.use('/users', usersRouter);

Congratulations, you’ve now got user management and authentication fully configured for your website! And you didn’t even have to write any code, manage any passwords, store anything in a database, etc!

How Authentication Works

Now that you’ve seen how to successfully setup authentication for your Node.js websites, let’s talk a bit more about how it works and explore the full authentication flow.

In order to explain each component, let’s assume that you’re visiting this website and are not currently logged into your account.

When you first click the Log In / Register button at the top of the page, the oidc-middleware library is going to redirect you to an Okta hosted domain (the authorization server). Here’s the sort of URL you’ll be redirected to:


https://dev-842917.oktapreview.com/login/login.htm?fromURI=/oauth2/v1/authorize/redirect?okta_key=qBpZVCpQIJlxUALtybnI9oajmFSOmWJNKL9pDpGtZRU

NOTE: You can fully customize this domain name, look, and feel using Okta.

Once you’ve landed on the authorization server page, you can either enter your account credentials and login immediately or create a new account. This functionality is handled by the authorization server completely.

If you enter your credentials and click the Sign In button on the authorization server, what happens behind the scenes is:

  • Your password is hashed and your credentials are checked against the Okta user database to determine whether or not they are correct
  • If your credentials are correct, a new session cookie is created for you on the Okta hosted domain (eg: dev-842917.oktapreview.com, in this case), and you are redirected to the redirect_uri setting you provided earlier when defining the ExpressOIDC object. In this case, you’d be redirected to http://localhost:3000/users/callback. When you’re redirected to this URL, the authorization server will also pass along a special code token. This is part of the OpenID Connect Authorization Code flow.
  • Your Express.js app will receive the request to /users/callback and service the request automatically using the oidc-middleware library’s built-in routes. The route servicing this URL will intercept the request and exchange the code token for an access and id token. This process of exchanging the code token is part of the OpenID Connect authorization code flow and is detailed more here: https://developer.okta.com/authentication-guide/implementing-authentication/auth-code#3-exchanging-the-code-for-tokens.
  • Once these tokens have been retrieved, the oidc-middleware library takes the user’s basic information embedded in the id token and stores it in a session cookie.
  • Then, the oidc-middleware library redirects you to the dashboard page as a fully logged-in user.
  • From this point on, each time your browser makes a request to the Express.js website, the cookie containing your profile information will be sent back to Express.js, so that the oidc-middleware library can recognize who you are and populate a req.userinfo object with your account data.

Once your session cookies have expired (or have been wiped via a logout procedure), the process starts all over again.

Create Styles

I’m not a professional designer, but even I can make this website look a little better.

Create a file named ./public/stylesheets/style.css and put the following CSS into it.

.top-bar a {
  text-decoration: none;
  color: inherit;
}

footer {
  border-top: 1px solid rgba(0,0,0,.1);
  margin-top: 4em !important;
  padding-top: 1em;
  text-align: center;
  margin-top: 1em;
}

h2 {
  margin-bottom: 2em;
}

.container {
  padding-top: 2em;
}

This will make the page styles look a little nicer.

Test Out Your New Login Portal

Now that your Express.js website is built, why not take it for a test drive? Start up your web server by running the npm start command, visit http://localhost:3000, and test things out!

using the site locally

You’ll notice a few things:

  • If you click the Log In / Register button at the top of the page, you can either create a new user account OR log into an existing one. This functionality is all provided by Okta’s authorization server automatically.
  • Once you’re logged in, you’ll be redirected to the /dashboard page, which will greet you by your first name. Remember that #{user.profile.firstName} variable in the ./views/dashboard.pug file earlier? That variable is now you actual user account since you’ve now plugged in all the appropriate middleware.
  • If you log out, then immediately click the Log In / Register button again, you’ll be instantly logged in without needing to re-enter your username and password. This is a feature of OpenID Connect — the authorization server remembers who you are for a set amount of time. This is the same way that Google Login and Facebook Login work!

If you’re already logged into your Okta account and instantly get logged into the dashboard, don’t worry. Just open a new incognito window in your browser and go through the flow there.

Learn More About Node.js and Authentication

I hope you enjoyed seeing how authentication works with OpenID Connect and Node.js. Building websites with user management can be a pain, but new protocols like OpenID Connect alongside providers like Okta make the process much simpler.

If you’d like to learn more about building web apps in Node, you might want to check out these other great posts:

Finally, please follow us on Twitter to find more great resources like this, request other topics for us to write about, and follow along with our new open source libraries and projects!

PS: If you liked this project and want to see the source code in one place, please go checkout and star the GitHub repository.

And… If you have any questions, please leave a comment below!

Source:: scotch.io

Use Angular and NativeScript to Build a Web and Mobile Application

By nativescript

Angular has been around for a few years now and since its release it has been useful when creating many different categories of applications, including web as well as mobile. The problem, at least for me, has always been that the experience for creating these various applications has been inconsistent and often confusing even though the driving technology has always been the same.

Things have gotten better now that custom schematics can be used with the official Angular CLI. So what does that mean for us? We can take a project created with the Angular CLI, add a schematic, let’s say for NativeScript, and end up with CLI compatible for both web and mobile.

We’re going to see how to use the Angular CLI to build a web and mobile compatible application with the NativeScript schematics.

Install the Required Global NPM Dependencies

Before we can create and maintain NativeScript applications from the Angular CLI, we need to make sure we have the appropriate global NPM dependencies available on our computer. Assuming that you already have Node.js installed and configured, execute the following from your command line:

npm install -g @angular/cli@6.1.0-beta.0
npm install -g @nativescript/schematics
npm install -g nativescript

The above commands will install the Angular CLI, the NativeScript CLI, and the NativeScript schematics for the Angular CLI. You have to remember that the schematics are only for creating and maintaining projects. The NativeScript CLI is still required for building and deploying the mobile applications.

Take note of the version of the Angular CLI being used. As of right now, 06/29/2018, beta.2 and rc.0 have some bugs that are scheduled to be fixed in rc.1. Until then, make sure you’re using beta.0 instead.

We won’t get into it in this tutorial, but your computer must also be configured for Android and iOS development if you wish to build locally. If you wish to do a cloud build and skip all the Android and iOS setup, you can check out NativeScript Sidekick.

Create a New Angular CLI Project with NativeScript Support

With the proper dependencies in place, we can add NativeScript support to an Angular CLI project. While you can do it to an existing project, we’re going to start with a fresh project for simplicity. From the command line, execute the following:

ng new angular-project

The above command will create a new Angular project, which by default, will be for web applications, not native mobile applications. We can add mobile application support by using the following, very simple, command:

ng add @nativescript/schematics

Make sure you had navigated into your project before executing the command above. You have to be in a project that was created with the Angular CLI, so if you had created a NativeScript project with the NativeScript CLI, I don’t think schematics can be included.

In the scenario that you’re truly creating a fresh code-sharing project, you can create an Angular with NativeScript project using the following single command as an alternative:

ng new --c=@nativescript/schematics --name=angular-project --shared

However, if you’re adding schematics to an existing project, the prior command should be used. More information on the schematics for NativeScript can be found in the official @nativescript/schematics repository.

Understanding the Schematic Changes and Process for Angular Development

When you add the NativeScript schematics to your Angular project, you’ll notice that it created quite a few files and even altered a few of the configuration files. Your original project should be in tact, so don’t worry about something destructive happening.

The most obvious thing that you’ll notice is that you have some .tns.ts and some .tns.html files. At first glance you’ll probably think that you now have to manage two different code-sets, which is not entirely true. NativeScript is a native mobile application framework which means you can’t use standard HTML markup for the UI. For this reason, yes you do have to maintain a web UI and a NativeScript UI. When it comes to the TypeScript, you could have a web version and a NativeScript version for everything, but you don’t need to. Where it makes sense is in the modules and routing areas since there are services like NativeScriptRoutingModule and RoutingModule which accomplish the same, but are specific to platform.

Have I confused you yet?

Let’s modify our new project so that we can see the power of having so many platforms under “almost” a single CLI. Starting with the project’s src/app/app.routing.tns.ts file, clone it to src/app/app.routing.ts and make it look like the following:

import { NgModule } from '@angular/core';
import { RouterModule } from '@angular/router';
import { Routes } from '@angular/router';

const routes: Routes = [
    { path: '', redirectTo: '/players', pathMatch: 'full' },
];

@NgModule({
    imports: [RouterModule.forRoot(routes)],
    exports: [RouterModule]
})
export class AppRoutingModule { }

If you haven’t noticed, the differences are in the naming of the modules being used. Since this file is for the web, we have removed the tns from the filename and used the vanilla Angular modules.

We’re not quite in the clear yet. We need to alter our project’s src/app/app.module.ts file to be more in line with the NativeScript version:

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppRoutingModule } from './app.routing';

import { AppComponent } from './app.component';
import { BarcelonaModule } from './barcelona/barcelona.module';

@NgModule({
    declarations: [
        AppComponent,
        AboutComponent
    ],
    imports: [
        BrowserModule,
        AppRoutingModule,
        BarcelonaModule
    ],
    providers: [],
    bootstrap: [AppComponent]
})
export class AppModule { }

If you’re coming from an established Angular project, you’ll likely be playing catchup with the NativeScript version instead. In other words the reverse of what we’re doing.

The last step is to fix up the src/app/app.component.html file. As of now, June 2018, we have a default landing page with no routing in our Angular project. We need to finish with the routing setup. In the project’s src/app/app.component.html, replace everything with the following:

<router-outlet></router-outlet>

We’re only trying to match the behavior between the two applications. Since the application is fresh, the NativeScript version accomplished a lot more than the web version. The initial content further validated this.

At this point our project is done, but what if we wanted to use the Angular CLI going forward with our project? How about we create a new component with the following command:

ng g component about

The above command will use the CLI to create a component called about and as a result you’ll end up with the following:

src/app/about/about.component.css
src/app/about/about.component.html
src/app/about/about.component.tns.html
src/app/about/about.component.ts
src/app/about/about.component.spec.ts

Where I’m going with this is that you can use the Angular CLI like you would any other Angular application. You’ll end up with a .tns.html file that you can add your custom UI for mobile to. There are plenty of other commands beyond generating components, so don’t feel that you’re limited.

Running an Angular CLI Project on Android or iOS with the NativeScript CLI

With the project created, altered, and ready to go, we can worry about running our application. In its simplest form, we can test that the project still works as a web application. From the command line, execute the following:

ng serve

When the command completes, you can visit http://localhost:4200 in your web browser to see it in action. To run the application on a mobile device, you can similarly run the following:

tns run ios --bundle

The above command will run the application on iOS. You can easily switch the ios part for android if that is better for you. The most important part of the command is the --bundle. If you don’t bundle the application, it will crash with a lot of confusing errors.

Conclusion

You just saw how to use the Angular CLI with a NativeScript Android and iOS application. This was a long awaited and insanely requested feature by both the Angular and NativeScript community. Having separation of CLIs for development that used Angular was doing no one any favors.

It is important to remember that NativeScript projects build native mobile applications. For this reason you can recycle your logic, but separate UI components must exist. Even though it sounds like a bad thing, it is a good thing because you can give your mobile and web applications a separate, but very polished user experience. If you want to give NativeScript a quick try, check out the NativeScript Playground. You can build your first truly native mobile app deployed on your own device in 3 minutes.

Source:: scotch.io

Building Text-to-Speech Apps for the Web

By Glad Chinda

App Demo

Having interacted with several apps over the years, there is a very high chance that you have interacted with apps that provide some form of voice experience. It could be an app with text-to-speech functionality like reading your text messages or notifications aloud. It could also be an app with voice recognition functionality like the popular Siri or Google Assistant.

With the advent of HTML5, there has been a very fast growth in the number of API available on the web platform. Over the years, we have come across API such as WebSocket, File, Geolocation, Notification, Battery, Vibration, DeviceOrientation, WebRTC, etc. Some of these API have gained very high support across various browsers. However, most of them are still in the experimental phase of development and are to be used with much caution.

Web Speech API

There are a couple of API known as the Web Speech API that have been developed to make it easy to seamlessly build varying kinds of voice applications and experiences for the web. These API are still pretty experimental, although there is increasing support for most of them across all the modern browsers.

The Web Speech API has broken into two major interfaces:

  • SpeechSynthesis – For text-to-speech applications. This allows apps to read out their text content using the device’s speech synthesiser. The available voice types are represented by a SpeechSynthesisVoice object, while the text to be uttered is represented by a SpeechSynthesisUtterance object. See the support table for the SpeechSynthesis interface to learn more about browser support.

  • SpeechRecognition – For applications that require asynchronous voice recognition. This allows apps to recognize voice context from an audio input. A SpeechRecognition object can be created using the constructor. The SpeechGrammar interface exists for representing the set of grammar that the app should recognise. See the support table for the SpeechRecognition interface to learn more about browser support.

In this tutorial, we will learn how we can use the SpeechSynthesis interface to build a simple text-to-speech app. Here is a demo screenshot of what the app will look like (without the sound):

The SpeechSynthesis Interface

The SpeechSynthesis interface is a very simple one with just a couple of methods and properties. To get a complete list of the available properties, methods and events, see the MDN documentation.

Getting a Reference

Getting a reference to a SpeechSynthesis object is very simple. The following code snippet shows how to it can be done.

var synthesis = window.speechSynthesis;

It is very useful to check if SpeechSynthesis is supported by the browser before using the functionality it provides. The following code snippet shows how to check for browser support.

if ('speechSynthesis' in window) {
  var synthesis = window.speechSynthesis;
  // do stuffs with synthesis
} else {
  console.log('Text-to-speech not supported.');
}

Getting Available Voices

Let’s build on our already existing code to get the available speech voices. The getVoices() method returns a list of SpeechSynthesisVoice objects representing all the available voices on the device.

Take a look at the following code snippet:

if ('speechSynthesis' in window) {

  var synthesis = window.speechSynthesis;

  // Regex to match all English language tags e.g en, en-US, en-GB
  var langRegex = /^en(-[a-z]{2})?$/i;

  // Get the available voices and filter the list to only have English speakers
  var voices = synthesis.getVoices().filter(voice => langRegex.test(voice.lang));

  // Log the properties of the voices in the list
  voices.forEach(function(voice) {
    console.log({
      name: voice.name,
      lang: voice.lang,
      uri: voice.voiceURI,
      local: voice.localService,
      default: voice.default
    })
  });

} else {
  console.log('Text-to-speech not supported.');
}

In the above snippet, we get the list of available voices on the device, and filter the list using the langRegex regular expression to ensure that we get voices for only English speakers. Finally, we loop through the voices in the list and log the properties of each to the console.

Constructing Speech Utterances

Let’s go ahead and see how we can construct speech utterances using the SpeechSynthesisUtterance constructor and setting values for the available properties. The following code snippet creates a very simple speech utterance for reading the text "Hello World".

if ('speechSynthesis' in window) {

  var synthesis = window.speechSynthesis;

  // Get the first `en` language voice in the list
  var voice = synthesis.getVoices().filter(function(voice) {
    return voice.lang === 'en';
  })[0];

  // Create an utterance object
  var utterance = new SpeechSynthesisUtterance('Hello World');

  // Set utterance properties
  utterance.voice = voice;
  utterance.pitch = 1.5;
  utterance.rate = 1.25;
  utterance.volume = 0.8;

  // Speak the utterance
  synthesis.speak(utterance);

} else {
  console.log('Text-to-speech not supported.');
}

Here, we first get the first en language voice from the list of available voices. Next, we create a new utterance using the SpeechSynthesisUtterance constructor. Then we set some of the properties on the utterance object like voice, pitch, rate and volume. Finally, we speak the utterance using the speak() method of SpeechSynthesis.

Utterance Limitation

There is a limit to the size of text that can be spoken in an utterance. The maximum length of the text that can be spoken in each utterance is 32,767 characters.

Notice, that we passed the text to be uttered in the constructor. You can also set the text to be uttered by setting the text property of the utterance object. This overrides whatever text that was passed in the constructor. Here is a simple example:

var synthesis = window.speechSynthesis;
var utterance = new SpeechSynthesisUtterance("Hello World");

// This overrides the text "Hello World" and is uttered instead
utterance.text = "My name is Glad.";

synthesis.speak(utterance);

Speaking an Utterance

In the previous code snippet, we have seen how to speak utterances by calling the speak() method on the SpeechSynthesis instance. We simply pass in the SpeechSynthesisUtterance instance as argument to the speak() method to speak the utterance.

var synthesis = window.speechSynthesis;

var utterance1 = new SpeechSynthesisUtterance("Hello World");
var utterance2 = new SpeechSynthesisUtterance("My name is Glad.");
var utterance3 = new SpeechSynthesisUtterance("I'm a web developer from Nigeria.");

synthesis.speak(utterance1);
synthesis.speak(utterance2);
synthesis.speak(utterance3);

There are a couple of other things you can do with the SpeechSynthesis instance such as pause, resume and cancel utterances. Hence the pause(), resume() and cancel() methods are available as well on the SpeechSynthesis instance.

Building the Text-to-Speech App

Getting Started

We have seen the basic aspects of the SpeechSynthesis interface. We will now start building our text-to-speech application. Before we begin, ensure that you have Node and NPM installed on your machine.

Run the following commands on your terminal to setup a project for the app and install the dependencies.

# Create new project directory
mkdir web-speech-app

# cd into the project directory
cd web-speech-app

# Initialize project
npm init -y

# Install dependencies
npm install express cors axios

Go ahead and modify the "scripts" section of the package.json file to look like the following snippet:

/* package.json */

"scripts": {
  "start": "node server.js"
}

Setting up the Server

Now that we have initialized a project for our application, we will proceed to setup a simple server for our app using Express.

Create a new server.js file and add the following content to it:

/* server.js */

const cors = require('cors');
const path = require('path');
const axios = require('axios');
const express = require('express');

const app = express();
const PORT = process.env.PORT || 5000;

app.set('port', PORT);

// Enable CORS(Cross-Origin Resource Sharing)
app.use(cors());

// Serve static files from the /public directory
app.use('/', express.static(path.join(__dirname, 'public')));

// A simple endpoint for fetching a random quote from QuotesOnDesign
app.get('/api/quote', (req, res) => {
  axios.get('http://quotesondesign.com/wp-json/posts?filter[orderby]=rand&filter[posts_per_page]=1')
    .then((response) => {
      const [ post ] = response.data;
      const { title, content } = post || {};

      return (title && content)
        ? res.json({ status: 'success', data: { title, content } })
        : res.status(500).json({ status: 'failed', message: 'Could not fetch quote.' });
    })
    .catch(err => res.status(500).json({ status: 'failed', message: 'Could not fetch quote.' }));
});

app.listen(PORT, () => console.log(`> App server is running on port ${PORT}.`));

Here, we set up a simple Node server using Express. We enable CORS(Cross-Origin Request Sharing) using the cors() middleware. We also use the express.static() middleware to serve static files from the /public directory in the project root. This will enable us serve our index page which we will be creating soon.

Finally, we setup a simple GET /api/quote route for fetching a random quote from the QuotesOnDesign API service. Notice also that we are using axios(a promise based HTTP client library) to make the HTTP request.

Here is what a sample response from the QuotesOnDesign API looks like:

[
  {
    "ID": 2291,
    "title": "Victor Papanek",
    "content": "<p>Any attempt to separate design, to make it a thing-by-itself, works counter to the inherent value of design as the primary, underlying matrix of life.</p>n",
    "link": "https://quotesondesign.com/victor-papanek-4/",
    "custom_meta": {
      "Source": "<a href="http://www.amazon.com/Design-Real-World-Ecology-Social/dp/0897331532">book</a>"
    }
  }
]

When we fetch a quote successfully, we return the quote’s title and content in the data field of the JSON response. Otherwise, we return a failure JSON response with a 500 HTTP status code.

Setting up the Index Page

Next, we will create a very simple index page for the app view. First create a new public folder in the root of your project. Next, create a new index.html file in the just created folder and add the following content to it:

<!-- public/index.html -->

<html>

<head>
    <title>Daily Quotes</title>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css" integrity="sha384-WskhaSGFgHYWDcbwN70/dfYBj47jz9qbsMId/iRN3ewGhXQFZCSftd1LZCfmhktB" crossorigin="anonymous">
</head>

<body class="position-absolute h-100 w-100">
    <div id="app" class="d-flex flex-wrap align-items-center align-content-center p-5 mx-auto w-50 position-relative"></div>

    <script src="https://unpkg.com/jquery/dist/jquery.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/feather-icons/dist/feather.min.js"></script>
    <script src="main.js"></script>
</body>

</html>

As you can see, we have a very simple index page for our app with just one

which will serve as the mount point for all the dynamic content of the app. Notice that we have added a link to the Bootstrap CDN to get some default Bootstrap 4 styling for our app. We have also included jQuery for DOM manipulations and Ajax requests, and Feather icons for elegant SVG icons.

The Main Script

Now we are down to the last piece that powers our app – the main script. Create a new main.js file in the public directory of your app and add the following content to it:

/* public/main.js */

jQuery(function($) {

  let app = $('#app');

  let SYNTHESIS = null;
  let VOICES = null;

  let QUOTE_TEXT = null;
  let QUOTE_PERSON = null;

  let VOICE_SPEAKING = false;
  let VOICE_PAUSED = false;
  let VOICE_COMPLETE = false;

  let iconProps = {
    'stroke-width': 1,
    'width': 48,
    'height': 48,
    'class': 'text-secondary d-none',
    'style': 'cursor: pointer'
  };

  function iconSVG(icon) {}

  function showControl(control) {}

  function hideControl(control) {}

  function getVoices() {}

  function resetVoice() {}

  function fetchNewQuote() {}

  function renderQuote(quote) {}

  function renderVoiceControls(synthesis, voice) {}

  function updateVoiceControls() {}

  function initialize() {}

  initialize();

});

Here, we use jQuery to execute a function when the DOM is loaded. We get a reference to the #app element and initialize some variables. We also declare a couple of empty functions which we will implement in the following sections. Finally, we call the initialize() function to initialize the application.

Notice the iconProps variable, which contains a couple of properties which will be used for rendering Feather icons as SVG to the DOM. Let’s go ahead and start implementing the functions.

Implement Basic Functions

Modify the public/main.js file to implement the following functions:

/* public/main.js */

// Gets the SVG markup for a Feather icon
function iconSVG(icon) {
  let props = $.extend(iconProps, { id: icon });
  return feather.icons[icon].toSvg(props);
}

// Shows an element
function showControl(control) {
  control.addClass('d-inline-block').removeClass('d-none');
}

// Hides an element
function hideControl(control) {
  control.addClass('d-none').removeClass('d-inline-block');
}

// Get the available voices, filter the list to have only English filters
function getVoices() {
  // Regex to match all English language tags e.g en, en-US, en-GB
  let langRegex = /^en(-[a-z]{2})?$/i;

  // Get the available voices and filter the list to only have English speakers
  VOICES = SYNTHESIS.getVoices()
    .filter(function (voice) { return langRegex.test(voice.lang) })
    .map(function (voice) {
      return { voice: voice, name: voice.name, lang: voice.lang.toUpperCase() }
    });
}

// Reset the voice variables to the defaults
function resetVoice() {
  VOICE_SPEAKING = false;
  VOICE_PAUSED = false;
  VOICE_COMPLETE = false;
}

The functions are pretty simple to understand but I will lay emphasis on some of them.

The iconSVG(icon) function takes a Feather icon name string as argument (e.g 'play-circle') and returns the SVG markup for the icon. Check here to see the complete list of available feather icons. Also check the Feather documentation to learn more about the API.

The getVoices() function uses the SYNTHESIS object to fetch the list of all the available voices on the device. Then, it filters the list using a regular expression to get the voices of only English speakers.

Fetching and Rendering Quotes

Next, we will implement the functions for fetching and rendering quotes on the DOM. Modify the public/main.js file to implement the following functions:

/* public/main.js */

function fetchNewQuote() {
  // Clean up the #app element
  app.html('');

  // Reset the quote variables
  QUOTE_TEXT = null;
  QUOTE_PERSON = null;

  // Reset the voice variables
  resetVoice();

  // Pick a voice at random from the VOICES list
  let voice = (VOICES && VOICES.length > 0)
    ? VOICES[ Math.floor(Math.random() * VOICES.length) ]
    : null;

  // Fetch a quote from the API and render the quote and voice controls
  $.get('/api/quote', function (quote) {
    renderQuote(quote.data);
    SYNTHESIS && renderVoiceControls(SYNTHESIS, voice || null);
  });
}

function renderQuote(quote) {

  // Create some markup for the quote elements
  let quotePerson = $('<h1 id="quote-person" class="mb-2 w-100"></h1>');
  let quoteText = $('<div id="quote-text" class="h3 py-5 mb-4 w-100 font-weight-light text-secondary border-bottom border-gray"></div>');

  // Add the quote data to the markup
  quotePerson.html(quote.title);
  quoteText.html(quote.content);

  // Attach the quote elements to the DOM
  app.append(quotePerson);
  app.append(quoteText);

  // Update the quote variables with the new data
  QUOTE_TEXT = quoteText.text();
  QUOTE_PERSON = quotePerson.text();

}

Here in the fetchNewQuote() method, we first reset the app element and variables. Then, we pick a voice randomly using Math.random() from the list of voices stored in the VOICES variable. Finally, we use $.get() to make an AJAX request to the /api/quote endpoint, to fetch a random quote and render the quote data to the view alongside the voice controls.

The renderQuote(quote) method receives a quote object as its argument and adds the contents to the DOM. Finally, it updates the quote variables: QUOTE_TEXT and QUOTE_PERSON.

Rendering the Voice Controls

If you noticed in the fetchNewQuote() function, we made a call to the renderVoiceControls() function. This function is responsible for rendering the controls for playing, pausing and stopping the voice(text-to-speech) output. It also renders the current voice being used and the language if available.

Go ahead and make the following modifications to the public/main.js file to implement the renderVoiceControls() function:

/* public/main.js */

function renderVoiceControls(synthesis, voice) {

  let controlsPane = $('<div id="voice-controls-pane" class="d-flex flex-wrap w-100 align-items-center align-content-center justify-content-between"></div>');

  let voiceControls = $('<div id="voice-controls"></div>');

  // Create the SVG elements for the voice control buttons
  let playButton = $(iconSVG('play-circle'));
  let pauseButton = $(iconSVG('pause-circle'));
  let stopButton = $(iconSVG('stop-circle'));

  // Helper function to enable pause state for the voice output
  let paused = function () {
    VOICE_PAUSED = true;
    updateVoiceControls();
  };

  // Helper function to disable pause state for the voice output
  let resumed = function () {
    VOICE_PAUSED = false;
    updateVoiceControls();
  };

  // Click event handler for the play button
  playButton.on('click', function (evt) {});

  // Click event handler for the pause button
  pauseButton.on('click', function (evt) {});

  // Click event handler for the stop button
  stopButton.on('click', function (evt) {});

  // Add the voice controls to their parent element
  voiceControls.append(playButton);
  voiceControls.append(pauseButton);
  voiceControls.append(stopButton);

  // Add the voice controls parent to the controlsPane element
  controlsPane.append(voiceControls);

  // If voice is available, add the voice info element to the controlsPane
  if (voice) {
    let currentVoice = $('<div class="text-secondary font-weight-normal"><span class="text-dark font-weight-bold">' + voice.name + '</span> (' + voice.lang + ')</div>');

    controlsPane.append(currentVoice);
  }

  // Add the controlsPane to the DOM
  app.append(controlsPane);

  // Show the play button
  showControl(playButton);

}

Here, we create container elements for the voice controls and the controls pane. We use the iconSVG() function we created earlier to get the SVG markup for our control buttons and create the button elements as well. We define the paused() and resumed() helper functions which will be used while setting up the event handlers for the buttons.

Finally, we render the voice control buttons and the voice info(if available) to the DOM. Also notice that we show only the play button initially.

Setting up the Event Handlers

Next, we will implement the click event handlers for the voice control buttons we defined in the previous section. Setup the event handlers as shown in the following code snippet:

playButton.on('click', function (evt) {
  evt.preventDefault();

  if (VOICE_SPEAKING) {

    // If voice is paused, it is resumed when the playButton is clicked
    if (VOICE_PAUSED) synthesis.resume();
    return resumed();

  } else {

    // Create utterances for the quote and the person
    let quoteUtterance = new SpeechSynthesisUtterance(QUOTE_TEXT);
    let personUtterance = new SpeechSynthesisUtterance(QUOTE_PERSON);

    // Set the voice for the utterances if available
    if (voice) {
      quoteUtterance.voice = voice.voice;
      personUtterance.voice = voice.voice;
    }

    // Set event listeners for the quote utterance
    quoteUtterance.onpause = paused;
    quoteUtterance.onresume = resumed;
    quoteUtterance.onboundary = updateVoiceControls;

    // Set the listener to activate speaking state when the quote utterance starts
    quoteUtterance.onstart = function (evt) {
      VOICE_COMPLETE = false;
      VOICE_SPEAKING = true;
      updateVoiceControls();
    }

    // Set event listeners for the person utterance
    personUtterance.onpause = paused;
    personUtterance.onresume = resumed;
    personUtterance.onboundary = updateVoiceControls;

    // Refresh the app and fetch a new quote when the person utterance ends
    personUtterance.onend = fetchNewQuote;

    // Speak the utterances
    synthesis.speak(quoteUtterance);
    synthesis.speak(personUtterance);

  }

});

pauseButton.on('click', function (evt) {
  evt.preventDefault();

  // Pause the utterance if it is not in paused state
  if (VOICE_SPEAKING) synthesis.pause();
  return paused();
});

stopButton.on('click', function (evt) {
  evt.preventDefault();

  // Clear the utterances queue
  if (VOICE_SPEAKING) synthesis.cancel();
  resetVoice();

  // Set the complete status of the voice output
  VOICE_COMPLETE = true;
  updateVoiceControls();
});

Here, we setup the click event listeners for the voice control buttons. When the play button is clicked, it starts speaking the utterances starting with the quoteUtterance and then the personUtterance. However, if the voice output is in a paused state, it resumes it.

Notice that we set VOICE_SPEAKING to true in the onstart event handler for the quoteUtterance. Also notice that we refresh the app and fetch a new quote when the personUtterance ends.

The pause button pauses the voice output, while the stop button ends the voice output and removes all utterances from the queue, using the cancel() method of the SpeechSynthesis interface. Notice that we call the updateVoiceControls() function each time to display the appropriate buttons.

Updating the Voice Controls

If you noticed, we have made a couple of calls and references to the updateVoiceControls() function in our previous code snippets. This function is responsible for updating the voice controls to display the appropriate controls based on the voice state variables.

Go ahead and make the following modifications to the public/main.js file to implement the updateVoiceControls() function:

/* public/main.js */

function updateVoiceControls() {

  // Get a reference to each control button
  let playButton = $('#play-circle');
  let pauseButton = $('#pause-circle');
  let stopButton = $('#stop-circle');

  if (VOICE_SPEAKING) {

    // Show the stop button if speaking is in progress
    showControl(stopButton);

    // Toggle the play and pause buttons based on paused state
    if (VOICE_PAUSED) {
      showControl(playButton);
      hideControl(pauseButton);
    } else {
      hideControl(playButton);
      showControl(pauseButton);
    }

  } else {
    // Show only the play button if no speaking is in progress
    showControl(playButton);
    hideControl(pauseButton);
    hideControl(stopButton);
  }

}

Here, we first get a reference to each of the voice control button elements. Then, we specify which voice control buttons should be visible at different states of the voice output.

Initialization Function

Finally, we will implement the initialize() function which is responsible for initializing the application. Add the following code snippet to the public/main.js file to implement the initialize() function.

function initialize() {
  if ('speechSynthesis' in window) {

    SYNTHESIS = window.speechSynthesis;

    let timer = setInterval(function () {
      let voices = SYNTHESIS.getVoices();

      if (voices.length > 0) {
        getVoices();
        fetchNewQuote();
        clearInterval(timer);
      }
    }, 200);

  } else {

    let message = 'Text-to-speech not supported by your browser.';

    // Create the browser notice element
    let notice = $('<div class="w-100 py-4 bg-danger font-weight-bold text-white position-absolute text-center" style="bottom:0; z-index:10">' + message + '</div>');

    fetchNewQuote();
    console.log(message);

    // Display non-support info on DOM
    $(document.body).append(notice);

  }
}

First, we check if speechSynthesis is available on the window global object, then we assign it to the SYNTHESIS variable if it is available. Next, we set up an interval for fetching the list of available voices.

We are using an interval here because there is a known asynchronous behavior with SpeechSynthesis.getVoices() that makes it return an empty array at the initial call – because the voices have not been loaded yet. The interval ensures that we get a list of voices before fetching a random quote and clearing the interval.

Now we have successfully completed our text-to-speech app. You can start the app by running npm start on your terminal. The app should start running on port 5000 if it is available. Visit http://localhost:5000 your browser to see the app.

If you did everything correctly, your app should look like the following screenshot:

Final Screenshot

Conclusion

In this tutorial, we have learnt how we can use the Web Speech API to build a very simple text-to-speech app for the web. You can learn more about the Web Speech API and also find some helpful resources here.

Although we tried as much as possible to keep the app simple, there are a couple of interesting features you can still implement and experiment with such as volume controls, voice pitch controls, speed/rate controls, percentage of text uttered, etc.

The complete source code for this tutorial checkout the web-speech-demo repository on GitHub.

Source:: scotch.io

.NET Microservices: Architecture For Containerized .NET Applications

Ben Nadel reviews .NET Microservices: Architecture For Containerized .NET Applications by Cesar de la Torre, Bill Wagner, and Mike Rousos. This is a FREE eBook from Microsoft that covers distributed system and service design in a containerized context. While it talks a great deal about .NET, the technology-agnostic parts of the book are well worth reading for non-dotnet developers (like himself)….

Source:: bennadel.com

The case for publish/subscribe in your software architecture considerations

By Adrian Matei

If you are developing a core platform in an enterprise you might experience the following pains, when core elements
need to synchronized with consuming clients of the platform.

Pains

  1. You might use a push mechanism to notify clients about an core element update (e.g. user or organisation data update).
    But what happens when a new client ist added? Well your core platform needs to be aware of it. This might imply code or configuration changes,
    new deployments etc. – ** it does not scale **
  2. If a client of the platform is not online the time the update notification is pushed, it will miss the update, which might lead to data inconsistency.

Pub/Subscribe to the rescue

Both issues are elegantly solved if you use a publish/subscribe mechanism. Your core platform, the publisher, will publish the update event to a message
broker, that will be consumed by one or several clients, subscribers. See the diagram below for the 1000 words, worth of explanation:

Continue reading The case for publish/subscribe in your software architecture considerations