Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
File renamed without changes.
63 changes: 63 additions & 0 deletions 1-server-side/express-App/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# Dependencies

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happened to chapter 4?

image

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

5-advanced should be named 4-advanced (think this was a Copilot mistake!), I'll get this updated.

node_modules/
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# Environment variables
.env
.env.local
.env.development.local
.env.test.local
.env.production.local

# Build outputs
build/

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Many of the sub-chapters in chapter 1 do not have readmes.

1-server-side/express-web-app-auth - does it even work? It has 2 sets of controllers, no auth code
1-server-side/express-web-app-deployment - no idea what this is, there doesn't seem to be any auth code
1-server-side/node-console-app - empty
nodejs-call-graph - it's just the web app?

We are missing a web api sample?

dist/
*.tgz

# OS generated files
.DS_Store
.DS_Store?
._*
.Spotlight-V100
.Trashes
ehthumbs.db
Thumbs.db

# IDE files
.vscode/
.idea/
*.swp
*.swo

# Logs
logs/
*.log

# Runtime data
pids/
*.pid
*.seed
*.pid.lock

# Coverage directory used by tools like istanbul
coverage/

# nyc test coverage
.nyc_output/

# Dependency directories
jspm_packages/

# Optional npm cache directory
.npm

# Optional REPL history
.node_repl_history

# Output of 'npm pack'
*.tgz

# Yarn Integrity file
.yarn-integrity
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
63 changes: 63 additions & 0 deletions 1-server-side/express-web-app-auth/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# Dependencies
node_modules/
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# Environment variables
.env
.env.local
.env.development.local
.env.test.local
.env.production.local

# Build outputs
build/
dist/
*.tgz

# OS generated files
.DS_Store
.DS_Store?
._*
.Spotlight-V100
.Trashes
ehthumbs.db
Thumbs.db

# IDE files
.vscode/
.idea/
*.swp
*.swo

# Logs
logs/
*.log

# Runtime data
pids/
*.pid
*.seed
*.pid.lock

# Coverage directory used by tools like istanbul
coverage/

# nyc test coverage
.nyc_output/

# Dependency directories
jspm_packages/

# Optional npm cache directory
.npm

# Optional REPL history
.node_repl_history

# Output of 'npm pack'
*.tgz

# Yarn Integrity file
.yarn-integrity
94 changes: 94 additions & 0 deletions 1-server-side/express-web-app-auth/App/app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
/*
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License.
*/

const path = require('path');
const express = require('express');
const session = require('express-session');
const { WebAppAuthProvider } = require('msal-node-wrapper');

const mainController = require('./controllers/mainController');
const authConfig = require('./authConfig.js');

async function main() {

// initialize express
const app = express();

/**
* Using express-session middleware. Be sure to familiarize yourself with available options
* and set them as desired. Visit: https://www.npmjs.com/package/express-session
*/
app.use(session({
secret: 'ENTER_YOUR_SECRET_HERE',
resave: false,
saveUninitialized: false,
cookie: {
httpOnly: true,
secure: process.env.NODE_ENV === "production", // set this to true on production
}
}));

app.use(express.urlencoded({ extended: false }));
app.use(express.json());

app.set('views', path.join(__dirname, './views'));
app.set('view engine', 'ejs');

app.use('/css', express.static(path.join(__dirname, 'node_modules/bootstrap/dist/css')));
app.use('/js', express.static(path.join(__dirname, 'node_modules/bootstrap/dist/js')));

app.use(express.static(path.join(__dirname, './public')));

try {
// instantiate the wrapper
const authProvider = await WebAppAuthProvider.initialize(authConfig);
// add the auth middleware before any route handlers
app.use(authProvider.authenticate());

// app routes
app.get('/', mainController.getHomePage);

// authentication routes
app.get(
'/signin',
(req, res, next) => {
return req.authContext.login({
postLoginRedirectUri: "/", // redirect here after login
})(req, res, next);
}
);

app.get(
'/signout',
(req, res, next) => {
return req.authContext.logout({
postLogoutRedirectUri: "/", // redirect here after logout
})(req, res, next);
}
);

// secure routes
app.get('/id',
authProvider.guard({
forceLogin: true // force user to login if not authenticated
}),
mainController.getIdPage
);

/**
* This error handler is needed to catch interaction_required errors thrown by MSAL.
* Make sure to add it to your middleware chain after all your routers, but before any other
* error handlers.
*/
app.use(authProvider.interactionErrorHandler());

return app;
} catch (error) {
console.log(error);
process.exit(1);
}
}

module.exports = main;
30 changes: 30 additions & 0 deletions 1-server-side/express-web-app-auth/App/authConfig.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/**
* For enhanced security, consider using client certificates instead of secrets.
* See README-use-certificate.md for more.
*/
const authConfig = {
auth: {
authority: "https://login.microsoftonline.com/Enter_the_Tenant_Info_Here",
clientId: "Enter_the_Application_Id_Here",
clientSecret: "Enter_the_Client_Secret_Here",
// clientCertificate: {
// thumbprint: "YOUR_CERT_THUMBPRINT",
// privateKey: fs.readFileSync('PATH_TO_YOUR_PRIVATE_KEY_FILE'),
// }
redirectUri: "/redirect",
},
system: {
loggerOptions: {
loggerCallback: (logLevel, message, containsPii) => {
if (containsPii) {
return;
}
console.log(message);
},
piiLoggingEnabled: false,
logLevel: 3,
},
}
};

module.exports = authConfig;
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
exports.getHomePage = (req, res, next) => {
const username = req.authContext.getAccount() ? req.authContext.getAccount().username : '';
res.render('home', { isAuthenticated: req.authContext.isAuthenticated(), username: username });
}

exports.getIdPage = (req, res, next) => {
const account = req.authContext.getAccount();

const claims = {
name: account.idTokenClaims.name,
preferred_username: account.idTokenClaims.preferred_username,
oid: account.idTokenClaims.oid,
sub: account.idTokenClaims.sub
};

res.render('id', {isAuthenticated: req.authContext.isAuthenticated(), claims: claims});
}
Loading