Skip to content

Commit 29dba25

Browse files
committed
perf(crypto): optimize CPU usage by switching to randomUUID and SHA-1
- Replace synchronous randomBytes with randomUUID for CSP nonces - Lazy-load CSP nonces using a property getter - Switch from SHA-256 to SHA-1 for faster internal key and schema caching Signed-off-by: Jeremy Ho <jujaga@gmail.com>
1 parent 7c29c36 commit 29dba25

File tree

5 files changed

+18
-10
lines changed

5 files changed

+18
-10
lines changed

src/app.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import compression from 'compression';
22
import cors from 'cors';
33
import express from 'express';
44
import helmet from 'helmet';
5-
import { randomBytes } from 'node:crypto';
5+
import { randomUUID } from 'node:crypto';
66
import { rateLimit } from 'express-rate-limit';
77
import favicon from 'serve-favicon';
88

@@ -46,7 +46,15 @@ app.use(express.json());
4646
app.use(express.urlencoded());
4747
app.use(favicon('src/public/favicon.ico'));
4848
app.use((_req: Request, res: Response<unknown, LocalContext>, next: NextFunction): void => {
49-
res.locals.cspNonce = randomBytes(32).toString('hex');
49+
let nonce: string | undefined;
50+
Object.defineProperty(res.locals, 'cspNonce', {
51+
get() {
52+
nonce ??= randomUUID();
53+
return nonce;
54+
},
55+
enumerable: true,
56+
configurable: true
57+
});
5058
next();
5159
});
5260
app.use(helmet());

src/services/helpers/lruCache.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ export async function cacheableRead<TB extends keyof DB, ID extends OperandValue
3434
const reader = (pk: ID) => repo.read(pk).executeTakeFirstOrThrow();
3535
if (!cacheEnabled) return await reader(id);
3636

37-
const hash = createHash('sha256').update(stringify(id)).digest('hex');
37+
const hash = createHash('sha1').update(stringify(id)).digest('hex');
3838
return cacheWrapper(`${repo.tableName}:${hash}`, reader, id);
3939
}
4040

@@ -55,7 +55,7 @@ export function cacheableUpsert<TB extends keyof DB>(
5555
): Promise<Selectable<DB[TB]>> {
5656
if (!cacheEnabled) return findWhereOrUpsert(repo, data);
5757

58-
const hash = createHash('sha256').update(stringify(data)).digest('hex');
58+
const hash = createHash('sha1').update(stringify(data)).digest('hex');
5959
return cacheWrapper(`${repo.tableName}:${hash}`, findWhereOrUpsert, repo, data);
6060
}
6161

src/validators/schema/schema.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ export function createAjvInstance(opts?: Options): Ajv {
4343
export function ensureSchemaId(schema: AnySchemaObject): AnySchemaObject {
4444
if (schema.$id) return schema;
4545

46-
const hash = createHash('sha256').update(stringify(schema)).digest('hex');
46+
const hash = createHash('sha1').update(stringify(schema)).digest('hex');
4747
return { $id: `schema:${hash}`, ...schema };
4848
}
4949

tests/unit/services/helpers/lruCache.test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,13 +49,13 @@ describe('cacheableRead', () => {
4949
expect(result).toEqual(readResult);
5050
expect(repo.read).toHaveBeenCalledWith('2.0.0');
5151

52-
const cacheKey = `pies.version:${createHash('sha256').update(stringify('2.0.0')).digest('hex')}`;
52+
const cacheKey = `pies.version:${createHash('sha1').update(stringify('2.0.0')).digest('hex')}`;
5353
expect(lruCache.get(cacheKey)).toEqual(readResult);
5454
});
5555

5656
it('returns cached result if available', async () => {
5757
const cachedResult = { id: '3.0.0' };
58-
const cacheKey = `pies.version:${createHash('sha256').update(stringify('3.0.0')).digest('hex')}`;
58+
const cacheKey = `pies.version:${createHash('sha1').update(stringify('3.0.0')).digest('hex')}`;
5959
lruCache.set(cacheKey, cachedResult);
6060

6161
const result = await cacheableRead(repo, '3.0.0', true);
@@ -103,7 +103,7 @@ describe('cacheableUpsert', () => {
103103
expect(repo.upsert).toHaveBeenCalledWith(mockData);
104104

105105
// Check cache
106-
const cacheKey = `pies.version:${createHash('sha256').update(stringify(mockData)).digest('hex')}`;
106+
const cacheKey = `pies.version:${createHash('sha1').update(stringify(mockData)).digest('hex')}`;
107107
expect(lruCache.get(cacheKey)).toEqual(upsertResult);
108108
});
109109
});

tests/unit/validators/schema/schema.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,8 @@ describe('ensureSchemaId', () => {
4343

4444
const result = ensureSchemaId(input);
4545

46-
// Verify format: "schema:" followed by a 64-character hex hash (SHA-256)
47-
expect(result.$id).toMatch(/^schema:[a-f0-9]{64}$/);
46+
// Verify format: "schema:" followed by a 40-character hex hash (SHA-1)
47+
expect(result.$id).toMatch(/^schema:[a-f0-9]{40}$/);
4848
expect(result.type).toBe('object');
4949
});
5050

0 commit comments

Comments
 (0)