Skip to content

Commit

Permalink
Merge 'patch' into 'minor'
Browse files Browse the repository at this point in the history
RobAndrewHurst committed Jan 20, 2025
2 parents 17aaee4 + 415a7a2 commit 08dee12
Showing 6 changed files with 121 additions and 22 deletions.
70 changes: 62 additions & 8 deletions express.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,65 @@
/**
@module express.js
@description
# Express.js 🚅
[Express](https://expressjs.com) is a minimal and flexible Node.js web application framework that provides a robust
set of features for web and mobile applications.
Our implementation provides the following endpoints and features:
- SAML authentication endpoints for Single Sign-On
- Rate-limited API endpoints for provider interactions
- Static file serving for documentation
- Security enhancements including header protection
The server implements the following core features:
- Rate limiting: 1000 requests per 1 min per IP
- Cookie parsing for session management
- JSON body parsing with 5MB limit for POST requests
- Static file serving with HTML extension support
## Security 🔐
- X-Powered-By header disabled
- Rate limiting enabled
- SAML authentication required for protected routes
## env
```env
PORT - Server port (default: 3000)
DIR - Base directory for routes
RATE_LIMIT - Maximum requests per window (default: 1000)
RATE_LIMIT_WINDOW - Time window in ms (default: 1 min)
```
@requires dotenv - Environment configuration loading
@requires express - Web application framework
@requires cookie-parser - HTTP cookie parsing middleware
@requires express-rate-limit - Rate limiting middleware
*/

require('dotenv').config();

const express = require('express');

const cookieParser = require('cookie-parser');
const rateLimit = require('express-rate-limit');

const app = express();

app.disable('x-powered-by');

const limiter = rateLimit({
windowMs: process.env.RATE_LIMIT_WINDOW ?? 1 * 60 * 1000, // 1 min
limit: process.env.RATE_LIMIT ?? 1000, //1000 requests per 1min
standardHeaders: 'draft-8',
legacyHeaders: false,
});

app.use(limiter);

app.use(
'/xyz',
express.static('docs', {
@@ -33,7 +87,13 @@ app.post(
api,
);

app.get(`${process.env.DIR || ''}/api/sign/:signer?`, api);
app.get(`${process.env.DIR || ''}/api/sign/:provider?`, api);

app.post(
`${process.env.DIR || ''}/api/sign/:provider?`,
express.json({ limit: '5mb' }),
api,
);

app.get(`${process.env.DIR || ''}/api/query/:template?`, api);

@@ -73,12 +133,6 @@ app.post(
api,
);

app.post(
`${process.env.DIR || ''}/saml/logout/callback`,
express.urlencoded({ extended: true }),
api,
);

app.get(`${process.env.DIR || ''}/view/:template?`, api);

app.get(`${process.env.DIR || ''}/:locale?`, api);
15 changes: 4 additions & 11 deletions jsdoc_xyz.json
Original file line number Diff line number Diff line change
@@ -1,14 +1,9 @@
{
"source": {
"include": [
"api",
"mod"
],
"include": ["api", "mod", "express.js"],
"includePattern": ".js$"
},
"plugins": [
"plugins/markdown"
],
"plugins": ["plugins/markdown"],
"opts": {
"encoding": "utf8",
"readme": "./api/README.md",
@@ -19,9 +14,7 @@
"theme_opts": {
"title": "XYZ",
"homepageTitle": "XYZ",
"static_dir": [
"./public/icons"
],
"static_dir": ["./public/icons"],
"favicon": "./public/icons/favicon.ico",
"menu": [
{
@@ -41,4 +34,4 @@
"hardwrap": false,
"idInHeadings": true
}
}
}
2 changes: 1 addition & 1 deletion lib/ui/Dataview.mjs
Original file line number Diff line number Diff line change
@@ -154,7 +154,7 @@ function show() {
}

//Show toolbar buttons if there are any
this.btnRow?.style.setProperty('display','block')
this.btnRow?.style.setProperty('display','flex')

this.target.style.display = 'block'
}
2 changes: 1 addition & 1 deletion lib/ui/Tabview.mjs
Original file line number Diff line number Diff line change
@@ -153,7 +153,7 @@ function addTab(entry) {
}

//Show toolbar buttons if there are any
entry.btnRow?.style.setProperty('display', 'block')
entry.btnRow?.style.setProperty('display', 'flex')
}

/**
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -44,6 +44,7 @@
"eslint": "^9.13.0",
"express": "^4.18.3",
"nodemon": "^3.1.7",
"uhtml": "^3.1.0"
"uhtml": "^3.1.0",
"express-rate-limit": "^7.5.0"
}
}
51 changes: 51 additions & 0 deletions tests/lib/ui/Dataview.test.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { mockLocation } from '../../utils/location.js';
/**
* ## lib.ui.Dataview
* @module ui/Dataview
*/
/**
* This function is used to test the Dataview method
* @function DataviewTest
*/
export async function DataviewTest(mapview) {
await codi.describe('UI: Dataview', async () => {
// Get the mocked location
const location = await mockLocation(mapview);
// Get the entry of type dataview
const entry = location.infoj.find(entry => entry.type === 'dataview');

await codi.it('dataview should have a show method', async () => {

codi.assertTrue(entry.show instanceof Function, 'The dataview entry has a show method.');

});

await codi.it('dataview btnRow should be display none initially', async () => {

codi.assertEqual(entry.btnRow.style.display, 'none', 'The dataview entry btnRow should be display none.');

});

await codi.it('dataview should have a hide method', async () => {

codi.assertTrue(entry.hide instanceof Function, 'The dataview entry has a hide method.');
});

await codi.it('dataview btnRow should be display true when show method called', async () => {

entry.show();
codi.assertEqual(entry.btnRow.style.display, 'flex', 'The dataview entry btnRow should be display flex.');

});

await codi.it('dataview btnRow should be display none when hide method called', async () => {

entry.hide();
codi.assertEqual(entry.btnRow.style.display, 'none', 'The dataview entry btnRow should be display none.');

});

// Remove the mocked location
location.remove();
});
}

0 comments on commit 08dee12

Please sign in to comment.