Skip to content

Commit

Permalink
feat: Add Azure Static Web Ap API to check roles after login
Browse files Browse the repository at this point in the history
  • Loading branch information
elwinschmitz committed Feb 2, 2024
1 parent 54f6134 commit 859a9aa
Show file tree
Hide file tree
Showing 10 changed files with 316 additions and 8 deletions.
23 changes: 19 additions & 4 deletions .azure/local-data/staticwebapp.config.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,32 +3,32 @@
"routes": [
{
"route": "/*.js",
"allowedRoles": ["anonymous"],
"headers": {
"Cache-Control": "immutable, no-transform, max-age=31536000"
}
},
{
"route": "/*.css",
"allowedRoles": ["anonymous"],
"headers": {
"Cache-Control": "immutable, no-transform, max-age=31536000"
}
},
{
"route": "/*.woff2",
"allowedRoles": ["anonymous"],
"headers": {
"Cache-Control": "immutable, no-transform, max-age=31536000"
}
},
{
"route": "/assets/*",
"allowedRoles": ["anonymous"],
"headers": {
"Cache-Control": "must-revalidate, no-transform, max-age=2592000"
}
},
{
"route": "/",
"allowedRoles": ["anonymous"]
},
{
"route": "/favicon.ico",
"allowedRoles": ["anonymous"]
Expand All @@ -41,6 +41,10 @@
"route": "/robots.txt",
"allowedRoles": ["anonymous"]
},
{
"route": "/frontdoor*",
"allowedRoles": ["anonymous"]
},
{
"route": "/.auth/login/twitter",
"statusCode": 404
Expand All @@ -66,12 +70,23 @@
"allowedRoles": ["aidworker"]
}
],
"responseOverrides": {
"401": {
"rewrite": "/frontdoor.html"
}
},
"trailingSlash": "auto",
"navigationFallback": {
"rewrite": "index.html",
"exclude": ["/assets/*", "/data/*"]
},
"globalHeaders": {
"Content-Security-Policy": "default-src 'self'; script-src 'self' 'unsafe-inline' https://*.in.applicationinsights.azure.com; style-src 'self' 'unsafe-inline'; img-src * 'self' data:; font-src 'self' data:; connect-src * 'self'; media-src * 'self'; object-src 'none'; frame-src 'none'; form-action 'none'; manifest-src 'self'"
},
"auth": {
"rolesSource": "/api/checkRoles"
},
"platform": {
"apiRuntime": "node:18"
}
}
1 change: 1 addition & 0 deletions .azure/login/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# Azure Login
10 changes: 10 additions & 0 deletions .azure/login/api/.funcignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
*.js.map
*.ts
.git*
.vscode
__azurite_db*__.json
__blobstorage__
__queuestorage__
local.settings.json
test
tsconfig.json
99 changes: 99 additions & 0 deletions .azure/login/api/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*

# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json

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

# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov

# Coverage directory used by tools like istanbul
coverage

# nyc test coverage
.nyc_output

# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt

# Bower dependency directory (https://bower.io/)
bower_components

# node-waf configuration
.lock-wscript

# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release

# Dependency directories
node_modules/
jspm_packages/

# TypeScript v1 declaration files
typings/

# Optional npm cache directory
.npm

# Optional eslint cache
.eslintcache

# Optional REPL history
.node_repl_history

# Output of 'npm pack'
*.tgz

# Yarn Integrity file
.yarn-integrity

# dotenv environment variables file
.env
.env.test

# parcel-bundler cache (https://parceljs.org/)
.cache

# next.js build output
.next

# nuxt.js build output
.nuxt

# vuepress build output
.vuepress/dist

# Serverless directories
.serverless/

# FuseBox cache
.fusebox/

# DynamoDB Local files
.dynamodb/

# TypeScript output
dist
out

# Azure Functions artifacts
bin
obj
appsettings.json
local.settings.json

# Azurite artifacts
__blobstorage__
__queuestorage__
__azurite_db*__.json
15 changes: 15 additions & 0 deletions .azure/login/api/host.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"version": "2.0",
"logging": {
"applicationInsights": {
"samplingSettings": {
"isEnabled": true,
"excludedTypes": "Request"
}
}
},
"extensionBundle": {
"id": "Microsoft.Azure.Functions.ExtensionBundle",
"version": "[4.*, 5.0.0)"
}
}
49 changes: 49 additions & 0 deletions .azure/login/api/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions .azure/login/api/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"private": true,
"dependencies": {
"@azure/functions": "^4.0.0"
},
"main": "src/functions/*.js"
}
40 changes: 40 additions & 0 deletions .azure/login/api/src/functions/checkRoles.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
const { app } = require('@azure/functions');

/**
* @param {import('@azure/functions').HttpRequest} request
* @param {import('@azure/functions').Context} context
*/
app.http('checkRoles', {
methods: ['POST'],
authLevel: 'anonymous',
handler: async (request, context) => {
if (
!request ||
!request.body ||
!request.body.identityProvider ||
!request.body.userDetails ||
request.identityProvider !== 'aad'
) {
return new Response(400, `Invalid request.`);
}

if (isEligible(request.body.userDetails)) {
return { roles: ['aidworker'] };
}

return { roles: [] };
},
});

/**
* @param {string} email
* @returns {boolean}
*/
function isEligible(email) {
const eligibleDomains = (process.env.HIA_ELIGIBLE_DOMAINS || '')
.split(',')
.map((domain) => domain.trim().toLowerCase());
const emailDomain = email.split('@')[1];

return !!emailDomain && eligibleDomains.includes(emailDomain.toLowerCase());
}
71 changes: 71 additions & 0 deletions .azure/login/frontdoor.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>NLRC Internal FAQ</title>

<meta
name="viewport"
content="width=device-width, initial-scale=1.0"
/>
<style>
html,
body {
margin: 0;
height: 100%;
}
body {
color: #fff;
font:
100% / 1.66 'Open Sans',
sans-serif;
background: linear-gradient(#fff 56px, #011e60 56px, #011e60);
}
h1 {
color: #011e60;
font-size: 1rem;
line-height: 56px;
text-align: center;
margin: 0;
}
main {
margin: 0 auto;
max-width: 500px;
}
a {
color: inherit;
}
.action {
display: block;
padding: 0.5em 1em;
color: #011e60;
background: #fff;
text-decoration: none;
border-radius: 0.25em;
}
</style>
</head>

<body>
<header>
<h1>NLRC Internal FAQ</h1>
</header>
<main>
<p>This website contains internal FAQs only.</p>
<p>
To view the public FAQ, visit:<br />
<a href="https://helpfulinformation-faq.redcross.nl/"
>https://helpfulinformation-faq.redcross.nl/</a
>
</p>
<br />
<p>
<a
href="/login"
class="action"
><strong>🔐 Login</strong></a
>
</p>
</main>
</body>
</html>
Loading

0 comments on commit 859a9aa

Please sign in to comment.