​Task management has never been easier

(This is a sponsored post.)
monday.com is a team management tool that is exceptionally suitable for any industry sector and by any sized team. It will perfectly serve a team of two or a team of hundreds spread around the globe, and it can manage multiple projects at once.
monday.com promotes effortless collaboration and transparency, it’s “cheetah fast," it displays status in as many as 20 different colors, and its status board can be customized to fit your needs …
The post ​Task management has never been easier appeared first on CSS-Tricks.

Link: https://ad.doubleclick.net/ddm/trackclk/N728909.1063086CSS-TRICKS.COM/B21510790.226075028;dc_trk_aid=424244274;dc_trk_cid=104360030;dc_lat=;dc_rdid=;tag_for_child_directed_treatment=;tfua=

An Event Apart

Just the other day in a Slack group I hang out in someone asked “what web design events is everyone going to and loving?" An Event Apart is always my immediate answer. I’ve gotten to speak a number of An Event Apart events, which is an incredible honor and always a good time. So from that perspective, I love it. I can tell you that it’s the most well-run conference I go to that gets all the details right.
But …
The post An Event Apart appeared first on CSS-Tricks.

Link: https://css-tricks.com/an-event-apart/

New on Wufoo: Form Manager Beta, File Manager Beta, Entry Manager Beta

Wufoo really is firing on all cylinders lately! As you may know, I’ve been using Wufoo here on this site, and pretty much every other site I’ve ever made, to power the web forms for over a decade. That’s a dang long time, which more than proves to me Wufoo is a form solution to trust. But also a product that improves!
There is a new Form Manager, Entry Manager, and File Manager.

Enable the beta stuff …
The post New on Wufoo: Form Manager Beta, File Manager Beta, Entry Manager Beta appeared first on CSS-Tricks.

Link: https://css-tricks.com/new-on-wufoo-form-manager-beta-file-manager-beta-entry-manager-beta/

​Experience a Simpler Cloud Computing Platform with DigitalOcean

(This is a sponsored post.)
From deploying static sites and blogging platforms to managing multiple client websites, DigitalOcean provides a flexible platform for developers and their teams to deliver an unparalleled end-user experience with a lightning-fast network, pre-configured applications, and a 99.99% uptime SLA. Simply let us know your needs and our solutions engineers will provide the best options available.
Direct Link to Article — Permalink…
The post ​Experience a Simpler Cloud Computing Platform with DigitalOcean appeared first on CSS-Tricks.

Link: https://ad.doubleclick.net/ddm/clk/423291670;224688389;t

Build a Basic CRUD App with Node and React

This article was originally published on the Okta developer blog. Thank you for supporting the partners who make SitePoint possible.
There are a lot of JavaScript frameworks out there today. It seems like I hear about a new one every month or so. They all have their advantages and are usually there to solve some sort of problem with an existing framework. My favorite to work with so far has been React. One of the best things about it is how many open source components and libraries there are in the React ecosystem, so you have a lot to choose from. This can be really difficult if you’re indecisive, but if you like the freedom to do things your way then React may be the best option for you.
In this tutorial, I’ll walk you through creating both a frontend web app in React and a backend REST API server in Node. The frontend will have a home page and a posts manager, with the posts manager hidden behind secure user authentication. As an added security measure, the backend will also not let you create or edit posts unless you’re properly authenticated.
The tutorial will use Okta’s OpenID Connect (OIDC) to handle authentication. On the frontend, the Okta React SDK will be used to request a token and provide it in requests to the server. On the backend, the Okta JWT Verifier will ensure that the user is properly authenticated, and throw an error otherwise.
The backend will be written with Express as a server, with Sequelize for modeling and storing data, and Epilogue for quickly creating a REST API without a lot of boilerplate.
Why React?
React has been one of the most popular JavaScript libraries for the past few years. One of the biggest concepts behind it, and what makes it so fast, is to use a virtual DOM (the Document Object Model, or DOM, is what describes the layout of a web page) and make small updates in batches to the real DOM. React isn’t the first library to do this, and there are quite a few now, but it certainly made the idea popular. The idea is that the DOM is slow, but JavaScript is fast, so you just say what you want the final output to look like and React will make those changes to the DOM behind the scenes. If no changes need to be made, then it doesn’t affect the DOM. If only a small text field changes, it will just patch that one element.
React is also most commonly associated with JSX, even though it’s possible to use React without JSX. JSX lets you mix HTML in with your JavaScript. Rather than using templates to define the HTML and binding those values to a view model, you can just write everything in JavaScript. Values can be plain JavaScript objects, instead of strings that need to be interpreted. You can also write reusable React components that then end up looking like any other HTML element in your code.
Here’s an example of some JSX code, that should be fairly simple to follow:
const Form = () => (

<label>
Name
<input value=”Arthur Dent" />
</label>
<label>
Answer to life, the universe, and everything
<input type="number" value={42} />
</label>
</form>
);

const App = () => (
<main>
<h1>Welcome, Hitchhiker!</h1>
<Form />
</main>
);

…and here’s what the same code would look like if you wrote it in plain JavaScript, without using JSX:
const Form = () => React.createElement(
"form",
null,
React.createElement(
"label",
null,
"Name",
React.createElement("input", { value: "Arthur Dent" })
),
React.createElement(
"label",
null,
"Answer to life, the universe, and everything",
React.createElement("input", { type: "number", value: 42 })
)
);

const App = () => React.createElement(
"main",
null,
React.createElement(
"h1",
null,
"Welcome, Hitchhiker!"
),
React.createElement(Form, null)
);

I find the JSX form much easier to read, but that’s just like, you know, my opinion, man.
Create Your React App
The quickest way to get started with React is to use Create React App, a tool that generates a progressive web app (PWA) with all the scripts and boilerplate tucked away neatly behind something called react-scripts, so you can just focus on writing code. It has all kinds of nice dev features as well, like updating the code whenever you make changes, and scripts to compile it down for production. You can use npm or yarn, but I’ll be using yarn in this tutorial.
To install create-react-app and yarn, simply run:
npm i -g create-react-app@1.5.2 yarn@1.7.0

NOTE: I’ll be adding version numbers to help future-proof this post. In general though, you’d be fine leaving out the version numbers (e.g. npm i -g create-react-app).
Now bootstrap your application with the following commands:
create-react-app my-react-app
cd my-react-app
yarn start

The default app should now be running on port 3000. Check it out at http://localhost:3000.

Create a Basic Homepage in React with Material UI
To keep things looking nice without writing a lot of extra CSS, you can use a UI framework. Material UI is a great framework for React that implements Google’s Material Design principles.
Add the dependency with:
yarn add @material-ui/core@1.3.1

Material recommends the Roboto font. You can add it to your project by editing public/index.html and adding the following line inside the head tag:
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500">

You can separate components into separate files to help keep things organized. First, create a couple new folders in your src directory: components, and pages
mkdir src/components
mkdir src/pages

Now create an AppHeader component. This will serve as the navbar with links to pages, as well as show the title and whether you’re logged in.
src/components/AppHeader.js
import React from ‘react’;
import {
AppBar,
Toolbar,
Typography,
} from ‘@material-ui/core’;

const AppHeader = () => (
<AppBar position="static">
<Toolbar>
<Typography variant="title" color="inherit">
My React App
</Typography>
</Toolbar>
</AppBar>
);

export default AppHeader;

Also create a homepage:
src/pages/Home.js
import React from ‘react’;
import {
Typography,
} from ‘@material-ui/core’;

export default () => (
<Typography variant="display1">Welcome Home!</Typography>
);

Now go ahead and actually just gut the sample app, replacing src/App.js with the following:
src/App.js
import React, { Fragment } from ‘react’;
import {
CssBaseline,
withStyles,
} from ‘@material-ui/core’;

import AppHeader from ‘./components/AppHeader’;
import Home from ‘./pages/Home’;

const styles = theme => ({
main: {
padding: 3 * theme.spacing.unit,
[theme.breakpoints.down(‘xs’)]: {
padding: 2 * theme.spacing.unit,
},
},
});

const App = ({ classes }) => (
<Fragment>
<CssBaseline />
<AppHeader />
<main className={classes.main}>
<Home />
</main>
</Fragment>
);

export default withStyles(styles)(App);

Material UI uses JSS (one of many flavors in the growingly popular trend of CSS in JavaScript), which is what withStyles provides.
The CssBaseline component will add some nice CSS defaults to the page (e.g. removing margins from the body), so we no longer need src/index.css. You can get rid of a couple other files too, now that we’ve gotten rid of most of the Hello World demo app.
rm src/index.css src/App.css src/logo.svg

In src/index.js, remove the reference to index.css (the line that says import ‘./index.css’;). While you’re at it, add the following as the very last line of src/index.js to turn on hot module reloading, which will make it so that changes you make automatically update in the app without needing to refresh the whole page:
if (module.hot) module.hot.accept();

At this point, your app should look like this:

Add Authentication to Your Node + React App with Okta
You would never ship your new app out to the Internet without secure identity management, right? Well, Okta makes that a lot easier and more scalable than what you’re probably used to. Okta is a cloud service that allows developers to create, edit, and securely store user accounts and user account data, and connect them with one or multiple applications. Our API enables you to:

Authenticate and authorize your users
Store data about your users
Perform password-based and social login
Secure your application with multi-factor authentication
And much more! Check out our product documentation

If you don’t already have one, sign up for a forever-free developer account. Log in to your developer console, navigate to Applications, then click Add Application. Select Single-Page App, then click Next.
Since Create React App runs on port 3000 by default, you should add that as a Base URI and Login Redirect URI. Your settings should look like the following:

Click Done to save your app, then copy your Client ID and paste it as a variable into a file called .env.local in the root of your project. This will allow you to access the file in your code without needing to store credentials in source control. You’ll also need to add your organization URL (without the -admin suffix). Environment variables (other than NODE_ENV) need to start with REACT_APP_ in order for Create React App to read them, so the file should end up looking like this:
.env.local
REACT_APP_OKTA_CLIENT_ID={yourClientId}
REACT_APP_OKTA_ORG_URL=https://{yourOktaDomain}

The easiest way to add Authentication with Okta to a React app is to use Okta’s React SDK. You’ll also need to add routes, which can be done using React Router. I’ll also have you start adding icons to the app (for now as an avatar icon to show you’re logged in). Material UI provides Material Icons, but in another package, so you’ll need to add that too. Run the following command to add these new dependencies:
yarn add @okta/okta-react@1.0.2 react-router-dom@4.3.1 @material-ui/icons@1.1.0

For routes to work properly in React, you need to wrap your whole application in a Router. Similarly, to allow access to authentication anywhere in the app, you need to wrap the app in a Security component provided by Okta. Okta also needs access to the router, so the Security component should be nested inside the router. You should modify your src/index.js file to look like the following:
src/index.js
import React from ‘react’;
import ReactDOM from ‘react-dom’;
import { BrowserRouter } from ‘react-router-dom’;
import { Security } from ‘@okta/okta-react’;

import App from ‘./App’;
import registerServiceWorker from ‘./registerServiceWorker’;

const oktaConfig = {
issuer: `${process.env.REACT_APP_OKTA_ORG_URL}/oauth2/default`,
redirect_uri: `${window.location.origin}/implicit/callback`,
client_id: process.env.REACT_APP_OKTA_CLIENT_ID,
};

ReactDOM.render(
<BrowserRouter>
<Security {…oktaConfig}>
<App />
</Security>
</BrowserRouter>,
document.getElementById(‘root’),
);
registerServiceWorker();

if (module.hot) module.hot.accept();

Now in src/App.js you can use Routes. These tell the app to only render a certain component if the current URL matches the given path. Replace your Home component with a route that only renders the component when pointing at the root URL (/), and renders Okta’s ImplicitCallback component for the /implicit/callback path.
src/App.js
— a/src/App.js
+++ b/src/App.js
@@ -1,4 +1,6 @@
import React, { Fragment } from ‘react’;
+import { Route } from ‘react-router-dom’;
+import { ImplicitCallback } from ‘@okta/okta-react’;
import {
CssBaseline,
withStyles,
@@ -21,7 +23,8 @@ const App = ({ classes }) => (
<CssBaseline />
<AppHeader />
<main className={classes.main}>
– <Home />
+ <Route exact path="/" component={Home} />
+ <Route path="/implicit/callback" component={ImplicitCallback} />
</main>
</Fragment>
);

Next, you need a login button. This file is a bit bigger because it contains some logic to check if the user is authenticated. I’ll show you the whole component first, then walk through what each section is doing:
src/components/LoginButton.js
import React, { Component } from ‘react’;
import {
Button,
IconButton,
Menu,
MenuItem,
ListItemText,
} from ‘@material-ui/core’;
import { AccountCircle } from ‘@material-ui/icons’;
import { withAuth } from ‘@okta/okta-react’;

class LoginButton extends Component {
state = {
authenticated: null,
user: null,
menuAnchorEl: null,
};

componentDidUpdate() {
this.checkAuthentication();
}

componentDidMount() {
this.checkAuthentication();
}

async checkAuthentication() {
const authenticated = await this.props.auth.isAuthenticated();
if (authenticated !== this.state.authenticated) {
const user = await this.props.auth.getUser();
this.setState({ authenticated, user });
}
}

login = () => this.props.auth.login();
logout = () => {
this.handleMenuClose();
this.props.auth.logout();
};

handleMenuOpen = event => this.setState({ menuAnchorEl: event.currentTarget });
handleMenuClose = () => this.setState({ menuAnchorEl: null });

render() {
const { authenticated, user, menuAnchorEl } = this.state;

if (authenticated == null) return null;
if (!authenticated) return <Button color="inherit" onClick={this.login}>Login</Button>;

const menuPosition = {
vertical: ‘top’,
horizontal: ‘right’,
};

return (
<div>
<IconButton onClick={this.handleMenuOpen} color="inherit">
<AccountCircle />
</IconButton>
<Menu
anchorEl={menuAnchorEl}
anchorOrigin={menuPosition}
transformOrigin={menuPosition}
open={!!menuAnchorEl}
onClose={this.handleMenuClose}
>
<MenuItem onClick={this.logout}>
<ListItemText
primary="Logout"
secondary={user && user.name}
/>
</MenuItem>
</Menu>
</div>
);
}
}

export default withAuth(LoginButton);

React components have a concept of state management. Each component can be passed props (in a component like <input type="number" value={3} />, type and number would be considered props). They can also maintain their own state, which has some initial values and can be changed with a function called setState. Any time the props or state changes, the component will rerender, and if changes need to be made to the DOM they will happen then. In a component, you can access these with this.props or this.state, respectively.
Here, you’re creating a new React component and setting the initial state values. Until you query the auth prop, you don’t know whether there’s a user or not, so you set authenticated and user to null. Material UI will use menuAnchorEl to know where to anchor the menu that lets you log the user out.
class LoginButton extends Component {
state = {
authenticated: null,
user: null,
menuAnchorEl: null,
};

// …
}

React components also have their own lifecycle methods, which are hooks you can use to trigger actions at certain stages of the component lifecycle. Here, when the component is first mounted you’ll check to see whether or not the user has been authenticated, and if so get some more details about the user, such as their name and email address. You also want to rerun this check whenever the component updates, but you need to be careful to only update the state when something is different, otherwise you’ll get yourself into an infinite loop (the component updates, so you give the component new values, which updates the component, you give it new values, etc.). The withAuth function is a Higher Order Component (HOC) which wraps the original component and returns another one containing the auth prop.
class LoginButton extends Component {
// …

componentDidUpdate() {
this.checkAuthentication();
}

componentDidMount() {
this.checkAuthentication();
}

async checkAuthentication() {
const authenticated = await this.props.auth.isAuthenticated();
if (authenticated !== this.state.authenticated) {
const user = await this.props.auth.getUser();
this.setState({ authenticated, user });
}
}

// …
}

export default withAuth(LoginButton);

The following functions are helper functions used later to log the user in or out, and open or close the menu. Writing the function as an arrow function ensures that this is referring to the instantiation of the component. Without this, if a function is called somewhere outside of the component (e.g. in an onClick event), you would lose access to the component and wouldn’t be able to execute functions on it or access props or state.
class LoginButton extends Component {
// …

login = () => this.props.auth.login();
logout = () => {
this.handleMenuClose();
this.props.auth.logout();
};

handleMenuOpen = event => this.setState({ menuAnchorEl: event.currentTarget });
}

All React components must have a render() function. This is what tells React what to display on the screen, even if it shouldn’t display anything (in which case you can return null).
When you’re not sure of the authentication state yet, you can just return null so the button isn’t rendered at all. Once Okta this.props.auth.isAuthenticated() returns, the value will either be true or false. If it’s false, you’ll want to provide a Login button. If the user is logged in, you can instead display an avatar icon that has a dropdown menu with a Logout button.
class LoginButton extends Component {
// …

render() {
const { authenticated, user, menuAnchorEl } = this.state;

if (authenticated == null) return null;
if (!authenticated) return <Button color="inherit" onClick={this.login}>Login</Button>;

const menuPosition = {
vertical: ‘top’,
horizontal: ‘right’,
};

return (
<div>
<IconButton onClick={this.handleMenuOpen} color="inherit">
<AccountCircle />
</IconButton>
<Menu
anchorEl={menuAnchorEl}
anchorOrigin={menuPosition}
transformOrigin={menuPosition}
open={!!menuAnchorEl}
onClose={this.handleMenuClose}
>
<MenuItem onClick={this.logout}>
<ListItemText
primary="Logout"
secondary={user && user.name}
/>
</MenuItem>
</Menu>
</div>
);
}
}

The next piece of the puzzle is to add this LoginButton component to your header. In order to display it on the right-hand side of the page, you can put an empty spacer div that has a flex value of 1. Since the other objects aren’t told to flex, the spacer will take up as much space as it can. Modify your src/components/AppHeader.js file like so:
src/components/AppHeader.js
— a/src/components/AppHeader.js
+++ b/src/components/AppHeader.js
@@ -3,16 +3,27 @@ import {
AppBar,
Toolbar,
Typography,
+ withStyles,
} from ‘@material-ui/core’;

-const AppHeader = () => (
+import LoginButton from ‘./LoginButton’;
+
+const styles = {
+ flex: {
+ flex: 1,
+ },
+};
+
+const AppHeader = ({ classes }) => (
<AppBar position="static">
<Toolbar>
<Typography variant="title" color="inherit">
My React App
</Typography>
+ <div className={classes.flex} />
+ <LoginButton />
</Toolbar>
</AppBar>
);

-export default AppHeader;
+export default withStyles(styles)(AppHeader);

You should now be able to log in and out of your app using the button in the top right.

When you click the Login button, you’ll be redirected to your Okta organization URL to handle authentication. You can log in with the same credentials you use in your developer console.

Once successfully signed in, you’re returned back to your app and should now see an icon showing that you’re logged in. If you click on the icon, you’ll see your name in a logout button. Clicking the button keeps you on the homepage but logs you out again.

Add a Node REST API Server
Now that users can securely authenticate, you can build the REST API server to perform CRUD operations on a post model. You’ll need to add quite a few dependencies to your project at this point:
yarn add @okta/jwt-verifier@0.0.12 body-parser@1.18.3 cors@2.8.4 dotenv@6.0.0 epilogue@0.7.1 express @4.16.3 sequelize@4.38.0 sqlite@2.9.2
yarn add -D npm-run-all@4.1.3

Create a new folder for the server under the src directory:
mkdir src/server

Now create a new file src/server/index.js. To keep this simple we will just use a single file, but you could have a whole subtree of files in this folder. Keeping it in a separate folder lets you watch for changes just in this subdirectory and reload the server only when making changes to this file, instead of anytime any file in src changes. Again, I’ll post the whole file and then explain some key sections below.
src/server/index.js
require(‘dotenv’).config({ path: ‘.env.local’ });

const express = require(‘express’);
const cors = require(‘cors’);
const bodyParser = require(‘body-parser’);
const Sequelize = require(‘sequelize’);
const epilogue = require(‘epilogue’);
const OktaJwtVerifier = require(‘@okta/jwt-verifier’);

const oktaJwtVerifier = new OktaJwtVerifier({
clientId: process.env.REACT_APP_OKTA_CLIENT_ID,
issuer: `${process.env.REACT_APP_OKTA_ORG_URL}/oauth2/default`,
});

const app = express();
app.use(cors());
app.use(bodyParser.json());

app.use(async (req, res, next) => {
try {
if (!req.headers.authorization) throw new Error(‘Authorization header is required’);

const accessToken = req.headers.authorization.trim().split(‘ ‘)[1];
await oktaJwtVerifier.verifyAccessToken(accessToken);
next();
} catch (error) {
next(error.message);
}
});

const database = new Sequelize({
dialect: ‘sqlite’,
storage: ‘./test.sqlite’,
});

const Post = database.define(‘posts’, {
title: Sequelize.STRING,
body: Sequelize.TEXT,
});

epilogue.initialize({ app, sequelize: database });

epilogue.resource({
model: Post,
endpoints: [‘/posts’, ‘/posts/:id’],
});

const port = process.env.SERVER_PORT || 3001;

database.sync().then(() => {
app.listen(port, () => {
console.log(`Listening on port ${port}`);
});
});

The following loads the environment variables we used in the React app. This way we can use the same env variables, and only have to set them in one place.
require(‘dotenv’).config({ path: ‘.env.local’ });

This sets up the HTTP server and adds some settings to allow for Cross-Origin Resource Sharing (CORS) and will automatically parse JSON.
const app = express();
app.use(cors());
app.use(bodyParser.json());

Here is where you check that a user is properly authenticated. First, throw an error if there is no Authorization header, which is how you will send the authorization token. The token will actually look like Bearer aLongBase64String. You want to pass the Base 64 string to the Okta JWT Verifier to check that the user is properly authenticated. The verifier will initially send a request to the issuer to get a list of valid signatures, and will then check locally that the token is valid. On subsequent requests, this can be done locally unless it finds a claim that it doesn’t have signatures for yet.
If everything looks good, the call to next() tells Express to go ahead and continue processing the request. If however, the claim is invalid, an error will be thrown. The error is then passed into next to tell Express that something went wrong. Express will then send an error back to the client instead of proceeding.
app.use(async (req, res, next) => {
try {
if (!req.headers.authorization) throw new Error(‘Authorization header is required’);

const accessToken = req.headers.authorization.trim().split(‘ ‘)[1];
await oktaJwtVerifier.verifyAccessToken(accessToken);
next();
} catch (error) {
next(error.message);
}
});

Here is where you set up Sequelize. This is a quick way of creating database models. You can Sequelize with a wide variety of databases, but here you can just use SQLite to get up and running quickly without any other dependencies.
const database = new Sequelize({
dialect: ‘sqlite’,
storage: ‘./test.sqlite’,
});

const Post = database.define(‘posts’, {
title: Sequelize.STRING,
body: Sequelize.TEXT,
});

Epilogue works well with Sequelize and Express. It binds the two together like glue, creating a set of CRUD endpoints with just a couple lines of code. First, you initialize Epilogue with the Express app and the Sequelize database model. Next, you tell it to create your endpoints for the Post model: one for a list of posts, which will have POST and GET methods; and one for individual posts, which will have GET, PUT, and DELETE methods.
epilogue.initialize({ app, sequelize: database });

epilogue.resource({
model: Post,
endpoints: [‘/posts’, ‘/posts/:id’],
});

The last part of the server is where you tell Express to start listening for HTTP requests. You need to tell sequelize to initialize the database, and when it’s done it’s OK for Express to start listening on the port you decide. By default, since the React app is using 3000, we’ll just add one to make it port 3001.
const port = process.env.SERVER_PORT || 3001;

database.sync().then(() => {
app.listen(port, () => {
console.log(`Listening on port ${port}`);
});
});

Now you can make a couple small changes to package.json to make it easier to run both the frontend and backend at the same time. Replace the default start script and add a couple others, so your scripts section looks like this:
The post Build a Basic CRUD App with Node and React appeared first on SitePoint.

Link: https://www.sitepoint.com/build-a-basic-crud-app-with-node-and-react/

Visual. Intuitive. Unlike Anything Else.

(This is a sponsored post.)
monday.com is a team management tool that’s found favor with more than 34,000 teams, including teams of two to teams of 2,000+, teams working for startups, and teams working on projects for Fortune 500 companies like AOL, Adidas, Samsung, and the Discovery Channel to name several.
monday.com is so easy to use, and its dashboard displays make such a superb use of color that it’s every bit as popular with non-tech oriented teams as …
The post Visual. Intuitive. Unlike Anything Else. appeared first on CSS-Tricks.

Link: https://synd.co/2uwQDOy

Build a React Native Application & Authenticate with OAuth 2.0

This article was originally published on the Okta Developer Blog. Thank you for supporting the partners who make SitePoint possible.
With Okta and OpenID Connect (OIDC), you can easily integrate authentication into a React Native application and never have to build it yourself again. OIDC allows you to authenticate directly against the Okta API, and this article shows you how to do just that in a React Native application. Today you’ll see how to log a user into your React Native application using an OIDC redirect via the AppAuth library.
React Native is a pretty slick framework. Unlike Ionic and other hybrid mobile frameworks, it allows you to use web technologies (React and JavaScript) to build native mobile apps. There is no browser or WebView involved, so developing a mobile app with React Native is similar to using the native SDK in that you’ll do all your testing on an emulator or device. There is no way to test it in your browser like there is with Ionic. This can be a benefit in that you don’t have to write code that works in-browser and on-device separately.
If you look at Google Trends, you can see that React Native is even more popular than Android and iOS for native development!

Today I’m going to show you how to develop a React Native app with the latest and greatest releases. At the time of this writing, that’s React 16.2.0 and React Native 0.54.0. You’ll create a new app, add AppAuth for authentication, authenticate with Okta, and see it running on both iOS and Android.

AppAuth is a client SDK for native apps to authenticate and authorize end-users using OAuth 2.0 and OpenID Connect. Available for iOS, macOS, Android and Native JS environments, it implements modern security and usability best practices for native app authentication and authorization.

Create Your React Native Application
React has a create-react-app command-line tool (CLI) that you can use to create new React apps. React Native has a similar tool called Create React Native App. Before you install it, make sure you have Node v6 or later installed.
Install create-react-native-app and create a new project called okta-rn:
npm install -g create-react-native-app
create-react-native-app okta-rn
cd okta-rn
npm start

Running these commands will result in your terminal prompting you with some options:
To view your app with live reloading, point the Expo app to this QR code.
You’ll find the QR scanner on the Projects tab of the app.

[QR Code]

Or enter this address in the Expo app’s search bar:

exp://172.31.98.12:19000

Your phone will need to be on the same local network as this computer.
For links to install the Expo app, please visit https://expo.io.

Logs from serving your app will appear here. Press Ctrl+C at any time to stop.

› Press a to open Android device or emulator, or i to open iOS emulator.
› Press q to display QR code.
› Press r to restart packager, or R to restart packager and clear cache.
› Press d to toggle development mode. (current mode: development)

If you’re on a Mac, press i to open iOS emulator. You will be prompted to install/open with Expo, then presented with the rendered App.js.

If you’re on Windows or Linux, I’d suggest trying the Android emulator or your Android device (if you have one). If it doesn’t work, don’t worry, I’ll show you how to make that work later on.
TIP: You can use TypeScript instead of JavaScript in your React Native app using Microsoft’s TypeScript React Native Starter. If you decide to go this route, I’d recommend following the steps to convert your app after you’ve completed this tutorial.
React Native and OAuth 2.0
In this example, I’ll use React Native App Auth, a library created by Formidable. The reason I’m using this library is three-fold: 1) they provide an excellent example that I was able to make work in just a few minutes, 2) it uses AppAuth (a mature OAuth client implementation), and 3) I was unable to get anything else working.

I tried react-native-oauth but discovered it required using an existing provider before adding a new one. I only wanted to have Okta as a provider. Also, it’s high number of issues and pull requests served as a warning sign.
I tried react-native-simple-auth but had problems getting the deprecated Navigator component to work with the latest React Native release.
I tried doing this OAuth 2 with React Native tutorial, but also had problems redirecting back to my app.

Create Native Application in Okta
Before you add AppAuth to your React Native application, you’ll need an app to authorize against. If you don’t have a free-forever Okta Developer account, get one today!
Log in to your Okta Developer account and navigate to Applications > Add Application. Click Native and click Next. Give the app a name you’ll remember (e.g., React Native), select Refresh Token as a grant type, in addition to the default Authorization Code. Copy the Login redirect URI (e.g., com.oktapreview.dev-158606:/callback) and save it somewhere. You’ll need this value when configuring your app.
Click Done and you should see a client ID on the next screen. Copy and save this value as well.
Add React Native AppAuth for Authentication
You’ll need to “eject” the native configuration for your app, which is normally hidden by create-react-native-app.
npm run eject

When prompted to answer questions, use the following answers:

Question
Answer

How would you like to eject from create-react-native-app?
React Native

What should your app appear as on a user’s home screen?
Okta RN

What should your Android Studio and Xcode projects be called?
OktaRN

To install App Auth for React Native, run the following commands:
npm i react-native-app-auth@2.2.0
npm i
react-native link

After running these commands, you have to configure the native iOS projects. I’ve copied the steps below for your convenience.
iOS Setup
React Native App Auth depends on AppAuth-ios, so you have to configure it as a dependency. The easiest way to do that is to use CocoaPods. To install CocoaPods, run the following command:
sudo gem install cocoapods

Create a Podfile in the ios directory of your project that specifies AppAuth-ios as a dependency. Make sure that OktaRN matches the app name you specified when running npm run eject.
platform :ios, ‘11.0’

target ‘OktaRN’ do
pod ‘AppAuth’, ‘>= 0.91’
end

Then run pod install from the ios directory. This can take a while the first time, even on a fast connection. Now is a good time to grab a coffee or a scotch! 🥃
Open your project in Xcode by running open OktaRN.xcworkspace from the ios directory.
If you intend to support iOS 10 and older, you need to define the supported redirect URL schemes in ios/OktaRN/Info.plist as follows:
CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLName</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleURLSchemes</key>
<array>
<string>{yourReversedOktaDomain}</string>
</array>
</dict>
</array>

Below is what mine looks like after I changed my app identifier and added this key.
<key>CFBundleIdentifier</key>
<string>com.okta.developer.reactnative.$(PRODUCT_NAME:rfc1034identifier)</string>
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLName</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleURLSchemes</key>
<array>
<string>com.oktapreview.dev-158606</string>
</array>
</dict>
</array>

Open AppDelegate.h in your Xcode project (OktaRN > OktaRN > AppDelegate.h) and add the lines with the + next to them below.
+ @protocol OIDAuthorizationFlowSession;

@interface AppDelegate : UIResponder <UIApplicationDelegate>
+ @property(nonatomic, strong, nullable) id<OIDAuthorizationFlowSession> currentAuthorizationFlow;
@property (nonatomic, strong) UIWindow *window;
@end

This property holds the authorization flow information that started before you redirect to Okta. After Okta authorizes you, it redirects to the redirect_uri that’s passed in.
The authorization flow starts from an openURL() app delegate method. To add it, open AppDelegate.m and import AppAuth.h.
#import “AppAuth.h"

Then at the bottom of the class (before @end), add the openURL() method.
– (BOOL)application:(UIApplication *)app
openURL:(NSURL *)url
options:(NSDictionary<NSString *, id> *)options {
if ([_currentAuthorizationFlow resumeAuthorizationFlowWithURL:url]) {
_currentAuthorizationFlow = nil;
return YES;
}
return NO;
}

Build Your React Native App
Replace the code in App.js with the following JavaScript. This code allows you to authorize, refresh your access token, and revoke it.
import React, { Component } from ‘react’;
import { UIManager, LayoutAnimation } from ‘react-native’;
import { authorize, refresh, revoke } from ‘react-native-app-auth’;
import { Page, Button, ButtonContainer, Form, Heading } from ‘./components’;

UIManager.setLayoutAnimationEnabledExperimental &&
UIManager.setLayoutAnimationEnabledExperimental(true);

const scopes = [‘openid’, ‘profile’, ’email’, ‘offline_access’];

type State = {
hasLoggedInOnce: boolean,
accessToken: ?string,
accessTokenExpirationDate: ?string,
refreshToken: ?string
};

const config = {
issuer: ‘https://{yourOktaDomain}/oauth2/default’,
clientId: ‘{clientId}’,
redirectUrl: ‘com.{yourReversedOktaDomain}:/callback’,
additionalParameters: {},
scopes: [‘openid’, ‘profile’, ’email’, ‘offline_access’]
};

export default class App extends Component<{}, State> {
state = {
hasLoggedInOnce: false,
accessToken: ”,
accessTokenExpirationDate: ”,
refreshToken: ”
};

animateState(nextState: $Shape<State>, delay: number = 0) {
setTimeout(() => {
this.setState(() => {
LayoutAnimation.easeInEaseOut();
return nextState;
});
}, delay);
}

authorize = async () => {
try {
const authState = await authorize(config);
this.animateState(
{
hasLoggedInOnce: true,
accessToken: authState.accessToken,
accessTokenExpirationDate: authState.accessTokenExpirationDate,
refreshToken: authState.refreshToken
},
500
);
} catch (error) {
Alert.alert(‘Failed to log in’, error.message);
}
};

refresh = async () => {
try {
const authState = await refresh(config, {
refreshToken: this.state.refreshToken
});

this.animateState({
accessToken: authState.accessToken || this.state.accessToken,
accessTokenExpirationDate:
authState.accessTokenExpirationDate || this.state.accessTokenExpirationDate,
refreshToken: authState.refreshToken || this.state.refreshToken
});
} catch (error) {
Alert.alert(‘Failed to refresh token’, error.message);
}
};

revoke = async () => {
try {
await revoke(config, {
tokenToRevoke: this.state.accessToken,
sendClientId: true
});
this.animateState({
accessToken: ”,
accessTokenExpirationDate: ”,
refreshToken: ”
});
} catch (error) {
Alert.alert(‘Failed to revoke token’, error.message);
}
};

render() {
const {state} = this;
return (
<Page>
{!!state.accessToken ? (
<Form>
<Form.Label>accessToken</Form.Label>
<Form.Value>{state.accessToken}</Form.Value>
<Form.Label>accessTokenExpirationDate</Form.Label>
<Form.Value>{state.accessTokenExpirationDate}</Form.Value>
<Form.Label>refreshToken</Form.Label>
<Form.Value>{state.refreshToken}</Form.Value>
</Form>
) : (
<Heading>{state.hasLoggedInOnce ? ‘Goodbye.’ : ‘Hello, stranger.’}</Heading>
)}

<ButtonContainer>
{!state.accessToken && (
<Button onPress={this.authorize} text="Authorize" color="#017CC0"/>
)}
{!!state.refreshToken && <Button onPress={this.refresh} text="Refresh" color="#24C2CB"/>}
{!!state.accessToken && <Button onPress={this.revoke} text="Revoke" color="#EF525B"/>}
</ButtonContainer>
</Page>
);
}
}

Make sure to adjust config with your settings.
const config = {
issuer: ‘https://{yourOktaDomain}/oauth2/default’,
clientId: ‘{clientId}’,
redirectUrl: ‘com.{yourReversedOktaDomain}:/callback’,

};

Change index.js to use OktaRN as the name of your app.
AppRegistry.registerComponent(‘OktaRN’, () => App);

This code uses styled-components, so you’ll need to install that as a dependency.
NOTE: Make sure to navigate into the root directory of your project before running the commands below.
npm i styled-components

Then copy the components directory into your project’s root directory from Formidable’s example.
svn export https://github.com/FormidableLabs/react-native-app-auth/trunk/Example/components

Grab the background image that’s referenced in the Page.js component too.
svn export https://github.com/FormidableLabs/react-native-app-auth/trunk/Example/assets

Run on iOS Simulator
Run your app with npm run ios.
You should see a screen that says “Hello, stranger.” Click on Authorize, and you’ll be prompted to continue or cancel.

Click Continue and you should see an Okta sign-in form. Enter your credentials, and you’ll be redirected back to the application.

You can click Refresh to watch the values for the access token and expire date change.
TIP: If animations happen slowly in iOS Simulator, toggle Debug > Slow Animations.
Android Setup
To configure the native Android project, start by upgrading the version of Gradle it uses.
cd android
./gradlew wrapper –gradle-version 4.6

React Native App Auth for Android depends on AppAuth-android, but you need to add the correct Android Support library version to your project.
Add the Google Maven repository to your android/build.gradle and upgrade the Android Tools dependency:
The post Build a React Native Application & Authenticate with OAuth 2.0 appeared first on SitePoint.

Link: https://scotch.io/tutorials/build-a-react-native-app-and-authenticate-with-oauth-20

​The State of Headless CMS Market

(This is a sponsored post.)
In March and April 2018, Kentico conducted the first global report about the state of headless CMS market. We surveyed 986 CMS practitioners in 85 countries about their opinions, adoption, and plans for using headless CMS. The survey contains valuable industry insights into topics such headless CMS awareness, preferred headless CMS models, current and future uptake of the headless CMS approach, and much more, from leading industry players.
Download your complimentary copy of the …
The post ​The State of Headless CMS Market appeared first on CSS-Tricks.

Link: https://synd.co/2zA8tFo

How to Add Auth to Your PWA with Okta and Stencil

This article was originally published on OKTA Blog. Thank you for supporting the partners who make SitePoint possible.
Progressive Web Applications (PWAs) are the newest technology on the web dev block, and they’ve arrived just in time to solve a growing problem. Many companies are struggling to keep isolated development teams across their organization up-to-date when new features are released. Some companies are even trying to decide if it’s worth the cost to develop both a web app and a mobile application. Not surprisingly, it’s a headache most companies are looking to avoid. PWAs can give companies a lot of the features they need from a mobile app without the need to manage multiple teams and codebases.
A PWA performs spectacularly when on a fast connection, and still performs well when offline or on Wi-Fi that’s not really fast enough to be called Wi-Fi (sometimes called “Lie-Fi”). It does so via caching and a JavaScript “Service Worker” that intercepts server calls and tries to serve the data from cache first, then when the server finally responds, it will replace the cached data with possibly “fresher” data from the server.
Recently, the Ionic team released a new project called Stencil. Stencil is a compiler that generates standards-compliant web components. Unlike most JavaScript frameworks, it doesn’t deliver a “framework” of code to the browser. It simply takes the code you write and uses its compiler to create vanilla components. You can also use Stencil’s compiler with your favorite framework. The Stencil starter project is the easiest way to get started with Stencil and produces a base application that scores nearly a 100% score on Lighthouse’s progressive web app scorecard.
To get started building a PWA using Stencil, clone the starter application and detach it from the GitHub remote.
WARNING: Stencil is not at a 1.0 release yet (as of this writing). So be aware that if you continue, you’re in early-adopter territory. If you find bugs, submit an issue.
Set Up the Starter Application
git clone https://github.com/ionic-team/stencil-starter.git first-stencil
cd first-stencil
git remote rm origin

Then, install all the dependencies that your new Stencil app will need.
npm install

You may see a couple of warnings from node-pre-gyp around fsevents. There’s nothing to see here. This is just to get around a nasty little npm bug.
Next, add the Okta Auth SDK (via CDN) to the bottom of the index.html page, right before the closing tag.
<script src=”https://ok1static.oktacdn.com/assets/js/sdk/okta-auth-js/1.8.0/okta-auth-js.min.js" type="text/javascript"></script>

While there is an npm package for Okta’s Auth SDK, Stencil has a hard time compiling it. Overall it works better for now if you just use the CDN to include it.
If you’re like me, the next thing you’ll want to do is run npm start and check the site with Lighthouse. If you do, you’ll notice that the score is kind of low. In particular, it doesn’t register a service worker or return a 200 when offline. That’s because it’s a development build, and generally, you don’t want the service worker intercepting server calls and returning cached data in development.
To ensure an accurate depiction of the kind of PWA you get out of the box with Stencil, make sure to run a production build using npm run build. Once you do, you’ll see a www folder and inside that folder, you’ll see a sw.js file. That’s your service worker!
Set Up Your Okta Application
If you haven’t already done so, create a free-forever developer account.
Once you’ve registered, click on Applications in the top menu. Then click Add Application.

You will then be taken to the application creation wizard. Choose Single-Page App and click Next at the bottom.

On the next screen, you’ll see the default settings provided by the single-page application template. Change the name of the application to something more descriptive, like “Stencil SPA”. Also, change the base URIs and the login redirect URIs settings to use port 3333 because that’s where your application will be running. The rest of the default settings are fine.

Click Done at the bottom.
Select your newly created application from the listing, and click on the General tab to view the general settings.

At the bottom, you’ll see a Client ID setting (yours won’t be blurred out, obviously). Copy this to use in your Stencil application. You will also need your Okta organization URL, which you can find at the top right of the dashboard page. It will probably look something like “https://dev-XXXXXX.oktapreview.com”.
Add the Authentication Component
In the components folder, add a new folder called app-auth. This is where your login page component will go. You can call it whatever you want, I’m just following the naming conventions set out by the starter app here. I’d definitely recommend deciding on a naming convention early and sticking with it.
Inside the newly created app-auth folder create two files: app-auth.css and app-auth.tsx. Start by creating the shell of the app-auth.tsx file.
import { Component } from ‘@stencil/core’;

@Component({
tag: ‘app-auth’,
styleUrl: ‘app-auth.css’
})
export class AppAuth {
render() {
return <div>Hello</div>;
}
}

If you are like I was, you might be thinking, “What kind of Frankenstein framework is this?”
You’ll notice the @Component decorator over the AppAuth class declaration like Angular, and then a render() method at the bottom like React. To me, that’s the beauty of Stencil. It takes some of the best parts of both popular frameworks and uses them to compile reusable components!
Add a Login Form
Next, you’ll add the JSX (that’s right, I said it) to the new component. Change the render() method to:
render() {
return (
<form class="app-auth">
<div class="form-item">
<label>
Username:
<input type="text" name="username" autocomplete="username" />
</label>
</div>
<div class="form-item">
<label>
Password:
<input
type="password"
name="password"
autocomplete="current-password"
/>
</label>
</div>
<div class="form-actions">
<button type="button" onClick={() => this.login()}>
Login
</button>
</div>
</form>
);
}

This is just a regular JSX form, but the login button’s onClick event is currently wired to function that doesn’t exist.
Add the Login Method’s Dependencies
Before you create that function, you’ll need to set up the OktaAuth JavaScript object to call the Okta API for authentication. You’ll add the object to the component’s state, so right below the class declaration, add the following line:
@State() authClient: any;

You will also have to import the @State() decorator. This is is used for values related to the internal state of the component. In the first import statement add State to the deconstruction list.
import { Component, State } from ‘@stencil/core’

You’ll also need to get the username and password values from the form itself, so add an @Element() to the code right below that @State() like you just created, so it read like this:
@State() authClient: any;
@Element() host: HTMLElement;

Then also add the @Element() decorator to the import so it reads:
import { Component, State, Element } from ‘@stencil/core’;

One last thing that the login() function will need is access to the router, so you can redirect the user to their profile page if their authentication is successful. You’ll need a class property, so add it right below the @Element.
@State() authClient: any;
@Element() host: HTMLElement;
@Prop() history: RouterHistory;

To import it, add the @Prop() decorator to the main import and then import the RouterHistory from @stencil/router right below the core import statement. The @Prop decorator is used to define properties that can be passed in to your component. In this case, it’s not a passed in value, but it could be if need be. Your final import section should read:
import { Component, Prop, State, Element, Listen } from ‘@stencil/core’;
import { RouterHistory } from ‘@stencil/router’;

Finally, to use the OktaAuth JavaScript library you brought in from the CDN, add a declaration for it right below the import statements.
declare const OktaAuth: any;

Add the Login Method
Now you included everything you’ll need to get the login function to authenticate users with your Okta organization. First, set up the OktaAuth object in the constructor of the AppAuth class. Right below the property for the RouterHistory object, add:
constructor() {
this.authClient = new OktaAuth({
clientId: ‘{yourClientId}’,
url: ‘https://{yourOktaDomain}.com’,
issuer: ‘default’
});
}

You can get your Client ID from that general settings page of your Okta application.
The post How to Add Auth to Your PWA with Okta and Stencil appeared first on SitePoint.

Link: https://www.sitepoint.com/how-to-add-auth-to-your-pwa-with-okta-and-stencil/

Build Custom Dashboards with MongoDB, Azure & Serverless Functions

This article was originally published on Ahmad Awais. Thank you for supporting the partners who make SitePoint possible.
TL;DR: I’m building a custom WordPress dashboard for an enterprise client which is powered by React.js on top of Node.js, with MongoDB Atlas as the database.
This dashboard uses several Microsoft Azure services, e.g., Cognitive Services, Azure App Services, and especially serverless Azure Functions. In this post, you’ll learn how to build a small module from it and the reason behind my choice of stack, apps, and products.

One of my enterprise clients who owns a huge networking and media company has a large-scale WordPress site set up. He recently consulted me about the possibility of building a custom WordPress dashboard (based on the WordPress REST API) — to help him make intelligent business decisions via Machine Learning and Artificial Intelligence.
With JavaScript eating up the world and WordPress adapting to the move by creating the Gutenberg project, I thought of an architecture/stack where WordPress would be our content layer, a familiar battle-tested environment that does its job well with a custom dashboard that’s built with JavaScript.
When you’re tasked to build a modern JavaScript application, you find yourself in a mix of different frameworks, tools, and dev workflows. The JavaScript ecosystem has grown a lot over the last couple of years. We have many, many good options available today.
So, after researching my options for a bit, I opted to use React.js on top of Node.js to start building the custom WordPress dashboard. While the project is in its ideation phase at the moment, I think it’s important that I share some of our goals here to define context behind my choice of the stack.
Custom WordPress Dashboard Goals
Imagine you own a large networking company where over 500 hotels (in three different countries) use your services to power their conference halls, IT meetings, and online property management like the sites and blogs. That’s what my client does.
Most of this is powered by a huge multi-site WordPress instance that manages everything for the hotels, websites, online booking, registrations, events, tickets, reviews, and comments. There’re also other systems running different software which are able to produce content via REST API.
We’ve set out to create a custom WordPress dashboard with many goals in mind, but I’m listing a few of them which are related to this particular article. Take a look at what I have built so far, it’s all based on serverless Azure functions — which are pretty awesome.

👀 High-level Data Reporting
The custom dashboard will report all the high-level data, e.g. things like live sales happening throughout my client’s portfolio (500+ hotels), entity/time-based and date-based breakdowns.
And how each of his franchise performing on a daily, weekly, monthly basis. All of this data is being fed to MongoDB Atlas. More on that later.
⚡ Serverless Automation
Most of the modules are built upon serverless architecture — which in this case provides huge benefits. All the automation is always running and the cost is paid as you go i.e. pay for what you use.
An initial rough estimate puts this solution 34% more economical than having a server VM running all the time. We are using Azure Functions for this serverless automation.
🔥 IoT (Internet of Things) Hub
There are about ~200 IT managers working for my client who have IoT enabled devices that feed data into several online projects. This custom dashboard also includes that data for making better decisions and connecting the whole registration, management, maintenance team’s hub into a single place.
As you might have already guessed, this project makes use of IoT Hub from Microsoft Azure to connect, monitor, and manage all of the IoT assets.
🤖 Machine Learning and Artificial Intelligence
We’re using a lot of different services from Microsoft Azure for the sake of making this dashboard artificially intelligent by Machine Learning.
There’s a huge dataset that is fed to the ML Studio which later helps us predict different decisions like space management, low registrations trends for IT events, and questions like why and when these things happen.
While the Machine Learning part is beyond the scope of this article, I still plan to touch base with some of the awesome Artificial Intelligence I’ve been able to cook in via Azure’s Cognitive Services.
🕰 Live & Real-time
One of the most important aspects of this custom dashboard is that it’s live and real-time. Which means I need a managed database that can cope with this amount of data and still stay highly available.
But at the same time, it’s for the management purposes and doesn’t need to have any impact on the WordPress sites. That is a crucial system design decision for this dashboard.
By that what I mean is we can do all sorts of experiments with this custom dashboard but it shouldn’t have any impact on the database/servers which are running the multi-site WordPress instance.
MongoDB & MongoDB Atlas
For this custom WordPress dashboard, I am using MongoDB Atlas as a DBaaS (Database as a Service). And I couldn’t be happier. When I first shared that I’d be using MongoDB, many developers had concerns.

Most of the questions asked why I’d add another layer of complexity by adding yet another database to the mix. Why not use the WordPress database as it is? To answer these questions and more I have prepared a list of reasons as to why I am using MongoDB Atlas.
♨ Dislike for RDBMS
I personally dislike relational databases. Most of the time, for me they get in the way of building applications. I have to completely get out of the app I am building, think about my database in the future and design a good schema which always ends up a bad exercise for my dev workflow. It’s counter-intuitive at best — at least for me, it is.
💸 HDD Is Cheap — CPU/RAM Is Not
Old databases were mostly designed to save disk space, among other things. This led to a plethora of problems like normalization, indexing, and made sharding, auto-scaling, and replication harder.
Nowadays, disk space is dirt cheap. On the other hand, CPU/RAM is not, and your sysadmin costs can skyrocket very quickly if you end up with a bad choice here.
Like you wanted to create a custom dashboard but your system design architect cost you two sysadmins with how they chose to design your system. Similarly, my client wanted a managed solution without having to hire a team of IT/DevOps folks — at least for an experimental custom dashboard.
🍀 MongoDB’s Pros

Schema-less. Flexible schema for the win. I don’t have to change anything, my regular app development workflow, creating a Node.js-based app that I am manipulating with JSON type data, I can just feed that into MongoDB and it just works.
Workflow-consistency. Creates documents the way my custom dashboard is represented. Sales, Videos, Talks, Comments, Reviews, Registrations, etc. all of that have similar data representation on the frontend and the backend — and even in the database. I manage 3rd party data via middleware. This consistency translates to clean code.
Ease of scale-out. It scales reads by using replica sets. Scales writes by using sharding (auto-balancing). Just fire up another machine and away you go. Most importantly, instead of vertical scaling via RDBMS, MongoDB lets you scale horizontally with different levels of consistency. That’s a big plus. ➕
Cost. Depends on which RDBMS of course, but MongoDB is free and can run on Linux, ideal for running on cheaper commodity kits.

🍃 Why MongoDB Atlas?
Well, now that I know MongoDB is the right database choice, there are so many different options to host your database. I can self-host on my Linux machine via DigitalOcean, use a cloud provider like AWS/Azure or a choose a DBaaS service specific to MongoDB.

But I want a fast, secure, and managed MongoDB solution that I can easily scale with the growth of the number of modules we attach in this custom WordPress dashboard. That’s MongoDB Atlas.

MongoDB Atlas is a cloud-hosted MongoDB service engineered and run by the same team that builds the database. And guess what, I trust that they follow the best operational practices since they are the ones who’re building MongoDB in the first place.

I want this custom dashboard to be self-managed, serverless, and using MongoDB Atlas saves me from worrying about software patching, backups, and reliable configuration setup for new DB updates. Again a big plus. ➕
Also, the fact that MongoDB Atlas is supported cross-platform as well as cross-region and across different cloud providers makes it a much better choice. I think each Cluster comes with two replica sets, ready to scale.
🔋 MongoDB Compass
Now that we are going to work with MongoDB, it’d be great to have a tool through which we can explore our database, view the changes, debug and so on. For this purpose, MongoDB again takes the lead with a product called MongoDB Compass. Take a look.

I suggest that you go ahead and download MongoDB Compass. It’s literally the best tool to visualize your MongoDB database. Here’s a set of features:

Visualize and explore: Take a look at your database, find out how things are looking, and even visualize stuff like maps/coordinates.
Insert, modify, and delete: You can also perform CRUD operations for your DB right from MongoDB compass. Makes testing easier.
Debug and optimize: Finally, analyze your data, debug it and even find out about performance issues right inside a great GUI for your database. This tool is a must-have if you work with MongoDB.
Extensible: And the best part is you can build your own plugins to extend MongoDB Compass. Here’s the documentation on building your own Compass plugins.
Enterprise Flavor: MongoDB Compass comes in a few flavors: Community (Free), and Enterprise (Licensed) — the Enterprise version is the one that lets you visualize DB schema.

✅ Getting Started with MongoDB Atlas
Let’s get started and build a simple module that’s part of the custom WordPress dashboard I am building. For this module, we are collecting all the sales related data. For that, we need a MongoDB instance, and of course we’re using MongoDB Atlas here.
Step #1: Go to MongoDB Atlas →
Go to the MongoDB Atlas site and register a completely free MongoDB instance hosted on AWS, with shared RAM and 512 MB storage. Click the Get Started Free button.

Step #2: Sign up at MongoDB Atlas →
Now go ahead and sign up with your email ID and fill up the details. It’s amazing that you can sign up and use a free MongoDB Atlas hosted DB instance, and they don’t even require you to add a credit card for that.

Step #3: Create the Cluster
Now you’ll be redirected to a page with a bunch of information about the new MongoDB Cluster you’re about to create. I suggest that you review this information, and move ahead by clicking the Create Cluster button at the bottom just like in the screenshot below.

Step #4: Create DB Username & Password
It’ll take a minute and your DB will be created. Once that happens, head over to the Security > MongoDB Users and click on the + ADD NEW USER button on the right, to create a new user for your database. Let’s keep all the other settings set to default for the sake of this intro-article.
I’m setting the user/pass as usermongo but you know better.

Step #5: Add IP to Whitelist for Access
To be able to access your MongoDB Atlas database, you need to setup the IP Whitelist with the IP of your server where your app is hosted. Authentication is beyond what I am discussing here so for the purpose of this demo let’s just allow everyone (obviously a bad practice in production).
So, again, head over to the Security > IP Whitelist and click on the + ADD IP ADDRESS button on the right, and finally ALLOW ACCESS FROM ANYWHERE button to allow the anonymous access.

Step #6: Connect via MongoDB Compass
Now that our DB’s IP access and a user has been created, we can pick up the connection string and use it to connect to our database with our MongoDB Compass application.
Go to Connect then choose Connect with MongoDB Compass and download Compass if you haven’t. Copy the URI Connection String. Finally, open Compass and it should be able to detect the connection string in your clipboard, allow it to connect to your database.
And you are set to visualize your database, analyze its performance, and even run complete CRUD operations. Awesome! 💯

Now that we have created a MongoDB Atlas and connected it with MongoDB Compass, we can move forward and start building our Node.js application.
WordPress REST API — FTW!
This WordPress based Node.js custom dashboard interacts with the WordPress instance via the WordPress REST API. Since this is a Node.js app, I am using an awesome library called wpapi written by K Adam White. He has also built a demo Express based WordPress app. That’s what I got inspired by while building this custom dashboard, so you’ll see a lot of it here.
🚀 WordPress Custom Router Based on Express
The router is set up with Express. Here’s a basic error handler and router template for using WordPress with express.
‘use strict’;

var express = require(‘express’);
var router = express.Router();
var siteInfoMiddleware = require(‘../middleware/site-info’);

// Set global site info on all routes
router.use(siteInfoMiddleware);

// Public Routes
// =============

router.get(‘/’, require(‘./index’));
router.get(‘/page/:page’, require(‘./index’));
router.get(‘/:slug’, require(‘./single’));
router.use(‘/tags/:tag’, require(‘./tag’));
router.use(‘/categories/:category’, require(‘./category’));

// Catch 404 and forward to error handler.
router.use(function (req, res, next) {
var err = new Error(‘Not Found’);
err.status = 404;
next(err);
});

// Error Handling
// ==============

// Development error handler will print stacktrace.
function developmentErrorRoute(err, req, res, next) {
res.status(err.status || 500);
res.render(‘error’, {
message: err.message,
error: err
});
}

// Production error handler. No stacktraces leaked to user.
function friendlyErrorRoute(err, req, res, next) {
res.status(err.status || 500);
res.render(‘error’, {
message: err.message,
error: {}
});
}

// Configure error-handling behavior
if (router.get(‘env’) === ‘development’) {
router.use(developmentErrorRoute);
} else {
router.use(friendlyErrorRoute);
}

module.exports = router;

View the code on Gist.
🎚 Basic Express Based Implementation
I am not hosting this entire thing on WordPress, but the initial plan was to do just that. If you want to go do that, you’d wanna build the index by querying all the info using the RSVP.hash utility for convenience and parallelism. For that here’s what you should do.
‘use strict’;

var wp = require( ‘../services/wp’ );
var contentService = require( ‘../services/content-service’ );
var pageNumbers = require( ‘../services/page-numbers’ );
var pageTitle = require( ‘../services/page-title’ );
var RSVP = require( ‘rsvp’ );

function getHomepage( req, res, next ) {
var pages = pageNumbers( req.params.page );

RSVP.hash({
archiveBase: ”,
pages: pages,
title: pageTitle(),
// Primary page content
posts: wp.posts().page( pages.current ),
sidebar: contentService.getSidebarContent()
}).then(function( context ) {
if ( req.params.page && ! context.posts.length ) {
// Invalid pagination: 404
return next();
}

res.render( ‘index’, context );
}).catch( next );
}

module.exports = getHomepage;

View the code on Gist.
🦏 Authentication Cooked In
For this setup, you’ll also need to authenticate your Node.js app by giving it the authentication data, which along with wpapi can be processed like this. Beware this is not always a best practice if you don’t use correct permissions and environment variables settings.
var WP = require( ‘wordpress-rest-api’ );
var _ = require( ‘lodash’ );

var config = _.pick( require( ‘./config’ ).wordpress, [
// Whitelist valid config keys
‘username’,
‘password’,
‘endpoint’
]);

var wp = new WP( config );

module.exports = wp;

View the code on Gist.
🦁 Site Content Accumulation
And finally, you are able to consume all the content by creating a content service which handles recursively fetching:

All the pages of a paged collection.
Your WordPress site’s info.
An alphabetized list of categories.
A specific category (specified by slug) from the content cache.
An alphabetized list of tags.
A specific tag (specified by slug) from the content cache
Other content required to have some feature parity with WP.

The code for this looks somewhat like this.
‘use strict’;

var wp = require( ‘./wp’ );
var cache = require( ‘./content-cache’ );
var _ = require( ‘lodash’ );
var RSVP = require( ‘rsvp’ );

/**
* Recursively fetch all pages of a paged collection
*
* @param {Promise} request A promise to a WP API request’s response
* @returns {Array} A promise to an array of all matching records
*/
function all( request ) {
return request.then(function( response ) {
if ( ! response._paging || ! response._paging.next ) {
return response;
}
// Request the next page and return both responses as one collection
return RSVP.all([
response,
all( response._paging.next )
]).then(function( responses ) {
return _.flatten( responses );
});
});
}

function siteInfo( prop ) {
var siteInfoPromise = cache.get( ‘site-info’ );

if ( ! siteInfoPromise ) {
// Instantiate, request and cache the promise
siteInfoPromise = wp.root( ‘/’ ).then(function( info ) {
return info;
});
cache.set( ‘site-info’, siteInfoPromise );
}

// Return the requested property
return siteInfoPromise.then(function( info ) {
return prop ? info[ prop ] : info;
});
}

/**
* Get an alphabetized list of categories
*
* All archive routes display a sorted list of categories in their sidebar.
* We generate that list here to ensure the sorting logic isn’t duplicated
* across routes.
*
* @method sortedCategories
* @return {Array} An array of category objects
*/
function sortedCategories() {
return all( wp.categories() ).then(function( categories ) {
return _.chain( categories )
.sortBy( ‘slug’ )
.value();
});
}

function sortedCategoriesCached() {
var categoriesPromise = cache.get( ‘sorted-categories’ );

if ( ! categoriesPromise ) {
categoriesPromise = sortedCategories();
cache.set( ‘sorted-categories’, categoriesPromise );
}

return categoriesPromise;
}

/**
* Get a specific category (specified by slug) from the content cache
*
* The WP API doesn’t currently support filtering taxonomy term collections,
* so we have to request all categories and filter them down if we want to get
* an individual term.
*
* To make this request more efficient, it uses sortedCategoriesCached.
*
* @method categoryCached
* @param {String} slug The slug of a category
* @return {Promise} A promise to the category with the provided slug
*/
function categoryCached( slug ) {
return sortedCategoriesCached().then(function( categories ) {
return _.findWhere( categories, {
slug: slug
});
});
}

/**
* Get a specific tag (specified by slug) from the content cache
*
* The WP API doesn’t currently support filtering taxonomy term collections,
* so we have to request all tags and filter them down if we want to get an
* individual term.
*
* To make this request more efficient, it uses the cached sortedTags promise.
*
* @method tagCached
* @param {String} slug The slug of a tag
* @return {Promise} A promise to the tag with the provided slug
*/
function tagCached( slug ) {
return sortedTagsCached().then(function( tags ) {
return _.findWhere( tags, {
slug: slug
});
});
}

/**
* Get an alphabetized list of tags
*
* @method sortedTags
* @return {Array} An array of tag objects
*/
function sortedTags() {
return all( wp.tags() ).then(function( tags ) {
return _.chain( tags )
.sortBy( ‘slug’ )
.value();
});
}

function sortedTagsCached() {
var tagsPromise = cache.get( ‘sorted-tags’ );

if ( ! tagsPromise ) {
tagsPromise = sortedTags();
cache.set( ‘sorted-tags’, tagsPromise );
}

return tagsPromise;
}

function getSidebarContent() {
return RSVP.hash({
categories: sortedCategoriesCached(),
tags: sortedTagsCached()
});
}

module.exports = {
// Recursively page through a collection to retrieve all matching items
all: all,
// Get (and cache) the top-level information about a site, returning the
// value corresponding to the provided key
siteInfo: siteInfo,
sortedCategories: sortedCategories,
sortedCategoriesCached: sortedCategoriesCached,
categoryCached: categoryCached,
tagCached: tagCached,
sortedTags: sortedTags,
sortedTagsCached: sortedTagsCached,
getSidebarContent: getSidebarContent
};

View the code on Gist.
🛠 Custom Routes & Sales Data
Finally, I have cooked in quite a few custom routes from where I can attain any kind of sales related data. For the particular architecture I have in place, I’m again using the RSVP.hash utility for convenience and parallelism. It works like a charm.
The post Build Custom Dashboards with MongoDB, Azure & Serverless Functions appeared first on SitePoint.

Link: https://www.sitepoint.com/build-custom-dashboards-with-mongodb-azure-serverless-functions/