This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| const path = require('path'); | |
| const HtmlWebpackPlugin = require('html-webpack-plugin'); | |
| const commonConfig = { | |
| mode: 'development', | |
| module: { | |
| rules: [ | |
| { | |
| test: /\.m?js$/, |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| { | |
| "name": "mfa-demo-node", | |
| "version": "1.0.0", | |
| "private": true, | |
| "scripts": { | |
| "build:dev": "webpack --watch", | |
| "server:dev": "nodemon build/server.js --watch build/server.js" | |
| }, | |
| "devDependencies": { | |
| "@babel/core": "^7.12.3", |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import { isArray } from 'util'; | |
| const fs = require('fs'); | |
| const storagePath = './storage'; | |
| const usersPath = `${storagePath}/users.json`; | |
| const initialUsers = { | |
| alan: { | |
| username: 'alan', |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import express from 'express'; | |
| import cookieSession from 'cookie-session'; | |
| import bodyParser from 'body-parser'; | |
| import { initStorage, getUser } from './storage'; | |
| initStorage(); | |
| const app = express(); | |
| app.use( |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import React, { useCallback, useState } from 'react'; | |
| import { login } from './api'; | |
| import Input from './Input'; | |
| export default function Login({ onLogin }) { | |
| const [username, setUsername] = useState(''); | |
| const [password, setPassword] = useState(''); | |
| const [invalidCredentials, setInvalidCredentials] = useState(false); | |
| const handleSubmit = useCallback( |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import React from 'react'; | |
| export default function Input({ label, ...props }) { | |
| return ( | |
| <div> | |
| <label htmlFor={props.id}>{label}</label> | |
| <br /> | |
| <input {...props} /> | |
| <br /> | |
| <br /> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| export async function login(username, password) { | |
| const res = await fetch('/login', { | |
| method: 'POST', | |
| headers: { 'Content-Type': 'application/json' }, | |
| body: JSON.stringify({ username, password }), | |
| }); | |
| if (res.status === 401) return {}; | |
| const user = await res.json(); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import React, { useState } from 'react'; | |
| import Login from './Login'; | |
| export default function App({ user }) { | |
| // user not logged in, show login form | |
| if (!user) return <Login />; | |
| return ( | |
| <div> | |
| Hello, {user.username}. <a href="/logout">Logout</a> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import moment from 'moment'; | |
| function HelloComponent() { | |
| const element = document.createElement('div'); | |
| element.innerText = `Now ${moment().format('L LT')}`; | |
| return element; | |
| } | |
| document.body.appendChild(HelloComponent()); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <script src="vendors.js"></script> |