Skip to content

Commit adbd74f

Browse files
authored
Merge pull request #4 from AegisJSProject/patch/refactor
patch/refactor
2 parents 087fa87 + 23a945b commit adbd74f

10 files changed

Lines changed: 81 additions & 336 deletions

File tree

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
## [v1.0.1] - 2025-11-26
11+
12+
### Added
13+
- Add default CSP using importmap and local package name
14+
15+
### Changed
16+
- Update modules to have default exports for use as module specifiers
17+
1018
## [v1.0.0] - 2025-11-24
1119

1220
Initial Release

compression.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,4 @@ export function useCompression(format = 'deflate') {
1616

1717
export const useGzip = useCompression('gzip');
1818
export const useDeflate = useCompression('deflate');
19-
export default useCompression;
19+
export default useDeflate;

cors.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,5 @@ export function useCORS({ allowCredentials = false } = {}) {
2020
}
2121
};
2222
}
23+
24+
export default useCORS();

csp.js

Lines changed: 54 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,31 @@
1-
export function useCSP(policy = {
2-
'default-src': ['\'self\''],
3-
}) {
1+
import { readFile } from 'node:fs/promises';
2+
import { imports } from '@shgysk8zer0/importmap';
3+
4+
const pkg = JSON.parse(await readFile(process.cwd() + '/package.json', { encoding: 'utf8' }));
5+
6+
export const importmap = typeof pkg.module === 'string'
7+
? JSON.stringify({
8+
imports: {
9+
...imports,
10+
[pkg.name]: pkg.module,
11+
[`${pkg.name}/`]: './',
12+
}
13+
})
14+
: JSON.stringify({
15+
imports: {
16+
...imports,
17+
[`${pkg.name}/`]: './',
18+
}
19+
});
20+
21+
const sri = async (input) => await Promise.resolve(input)
22+
.then(json => new TextEncoder().encode(json))
23+
.then(bytes => crypto.subtle.digest('SHA-384', bytes))
24+
.then(hash => 'sha384-' + new Uint8Array(hash).toBase64());
25+
26+
export const integrity = await sri(importmap);
27+
28+
export function useCSP(policy = { 'default-src': ['\'self\''] }) {
429
const policyStr = Object.entries(policy).map(([name, values]) => {
530
return `${name} ${Array.isArray(values) ? values.join(' ') : values}`;
631
}).join('; ');
@@ -11,3 +36,29 @@ export function useCSP(policy = {
1136
}
1237
};
1338
}
39+
40+
const DEFAULT_SRC = ['\'self\''];
41+
const SCRIPT_SRC = ['\'self\'', 'https://unpkg.com/@shgysk8zer0/', 'https://unpkg.com/@kernvalley/', 'https://unpkg.com/@aegisjsproject/', `'${integrity}'`];
42+
const STYLE_SRC = ['\'self\'', 'https://unpkg.com/@agisjsproject/', 'blob:'];
43+
const IMAGE_SRC = ['\'self\'', 'https://i.imgur.com/', 'https://secure.gravatar.com/avatar/', 'blob:', 'data:'];
44+
const MEDIA_SRC = ['\'self\'', 'blob:'];
45+
const CONNECT_SRC = ['\'self\''];
46+
const FONT_SRC = ['\'self\''];
47+
const FRAME_SRC = ['\'self\'', 'https://www.youtube-nocookie.com'];
48+
const TRUSTED_TYPES = ['aegis-sanitizer#html'];
49+
50+
export const useDefaultCSP = ({ ...rest } = {}) => useCSP({
51+
'default-src': DEFAULT_SRC,
52+
'script-src': SCRIPT_SRC,
53+
'style-src': STYLE_SRC,
54+
'img-src': IMAGE_SRC,
55+
'media-src': MEDIA_SRC,
56+
'font-src': FONT_SRC,
57+
'frame-src': FRAME_SRC,
58+
'connect-src': CONNECT_SRC,
59+
'trusted-types': TRUSTED_TYPES,
60+
'require-trusted-types-for': '\'script\'',
61+
...rest
62+
});
63+
64+
export default useDefaultCSP;

geo.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
const ENDPOINT = 'https://api.ipgeolocation.io/ipgeo';
2-
const ENV_NAME = 'IPGEOLOCATION';
2+
const ENV_NAME = 'IPGEOLOCATION_KEY';
33
const cache = new Map();
44
let warned = false;
55

66
/**
77
* Adds a `geo` object containing geoip data to the request context object.
88
*
9-
* @param {string} [apiKey=process.env.IPGEOLOCATION] The API key for `api.ipgeolocation.io`, defaulting to one provided by an environment variable.
9+
* @param {string} [apiKey=process.env.IPGEOLOCATION_KEY] The API key for `api.ipgeolocation.io`, defaulting to one provided by an environment variable.
1010
* @returns {Function} The middleware context modifying callback.
1111
*/
1212
export function useGeo(apiKey = process.env[ENV_NAME]) {
@@ -65,3 +65,5 @@ export function useGeo(apiKey = process.env[ENV_NAME]) {
6565
}
6666
};
6767
}
68+
69+
export default typeof process.env[ENV_NAME] === 'string' ? useGeo(process.env[ENV_NAME]) : () => null;

http.config.js

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,5 @@
11
import { useRateLimit } from './rate-limit.js';
2-
import { useCSP } from './csp.js';
3-
import { useCORS } from './cors.js';
42
import { checkCacheItem, setCacheItem } from './cache.js';
5-
import { useGeo } from './geo.js';
6-
import { useCompression } from './compression.js';
73
import { imports } from '@shgysk8zer0/importmap';
84

95
const visits = new Map();
@@ -21,21 +17,15 @@ export default {
2117
console.log(`${req.url} visit count: ${visits.get(req.url)}`);
2218
},
2319
useRateLimit({ timeout: 60_000, maxRequests: 100 }),
24-
useGeo(process.env.IPGEOLOCATION_KEY),
25-
'./req-id.js',
20+
'@aegisjsproject/http-utils/geo.js',
21+
'@aegisjsproject/http-utils/request-id.js',
2622
checkCacheItem,
2723
],
2824
responsePostprocessors: [
29-
useCompression('deflate'),
25+
'@aegisjsproject/http-utils/compression.js',
3026
setCacheItem,
31-
useCORS({ allowCredentials: true }),
32-
useCSP({
33-
'default-src': '\'none\'',
34-
'script-src': ['\'self\'', 'https://unpkg.com/@shgysk8zer0/', 'https://unpkg.com/@shgysk8zer0/'],
35-
'img-src': '\'self\'',
36-
'media-src': '\'self\'',
37-
'connect-src': ['\'self\'', 'http://localhost:*/'],
38-
}),
27+
'@aegisjsproject/http-utils/cors.js',
28+
'@aegisjsproject/http-utils/csp.js',
3929
(response, { request }) => {
4030
if (request.destination === 'document') {
4131
response.headers.append('Link', `<${imports['@shgysk8zer0/polyfills']}>; rel="preload"; as="script"; fetchpriority="high"; crossorigin="anonymous"; referrerpolicy="no-referrer"`);

logger.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
export const logger = reqOrResp => console.log(reqOrResp);
2+
export default logger;

0 commit comments

Comments
 (0)