mirror of
https://github.com/dcarrillo/atalaya.git
synced 2026-05-18 06:24:12 +00:00
refactor: move auth.ts into a shared location rather than importing across workspace boundaries (#11)
This commit is contained in:
@@ -37,6 +37,4 @@ jobs:
|
|||||||
run: npm run build:pages
|
run: npm run build:pages
|
||||||
|
|
||||||
- name: Run tests
|
- name: Run tests
|
||||||
run: |
|
run: npm run test
|
||||||
npm run test
|
|
||||||
npm run test:pages
|
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ vitest run src/path/to.test.ts # single test (no npx needed)
|
|||||||
```bash
|
```bash
|
||||||
npm run dev:pages # astro dev
|
npm run dev:pages # astro dev
|
||||||
npm run build:pages # astro build → status-page/dist/
|
npm run build:pages # astro build → status-page/dist/
|
||||||
npm run test:pages # vitest run (auth tests)
|
|
||||||
npm run check:pages # astro check + tsc --noEmit
|
npm run check:pages # astro check + tsc --noEmit
|
||||||
npm run lint:pages # eslint (astro plugin)
|
npm run lint:pages # eslint (astro plugin)
|
||||||
```
|
```
|
||||||
@@ -39,6 +39,8 @@ npm run lint:pages # eslint (astro plugin)
|
|||||||
|
|
||||||
Before commit: `npm run check && npm run test && npm run build:pages && npm run check:pages`
|
Before commit: `npm run check && npm run test && npm run build:pages && npm run check:pages`
|
||||||
|
|
||||||
|
## Verification order
|
||||||
|
|
||||||
`npm run check` = typecheck + Oxlint (worker) + ESLint (dedup via `eslint-plugin-oxlint`). Pages uses `eslint-plugin-astro`.
|
`npm run check` = typecheck + Oxlint (worker) + ESLint (dedup via `eslint-plugin-oxlint`). Pages uses `eslint-plugin-astro`.
|
||||||
|
|
||||||
## Gotchas
|
## Gotchas
|
||||||
|
|||||||
@@ -387,9 +387,6 @@ npm run build:pages
|
|||||||
# Worker tests
|
# Worker tests
|
||||||
npm run test
|
npm run test
|
||||||
|
|
||||||
# Status page tests
|
|
||||||
npm run test:pages
|
|
||||||
|
|
||||||
# Type checking and linting
|
# Type checking and linting
|
||||||
npm run check # worker
|
npm run check # worker
|
||||||
npm run check:pages # pages (astro check + tsc)
|
npm run check:pages # pages (astro check + tsc)
|
||||||
|
|||||||
@@ -20,7 +20,6 @@
|
|||||||
"check:fix": "npm run lint:fix && npm run format",
|
"check:fix": "npm run lint:fix && npm run format",
|
||||||
"dev:pages": "npm run dev --workspace=status-page",
|
"dev:pages": "npm run dev --workspace=status-page",
|
||||||
"build:pages": "npm run build --workspace=status-page",
|
"build:pages": "npm run build --workspace=status-page",
|
||||||
"test:pages": "npm run test --workspace=status-page",
|
|
||||||
"check:pages": "npm run typecheck --workspace=status-page && npm run lint:pages && npm run format:pages:check",
|
"check:pages": "npm run typecheck --workspace=status-page && npm run lint:pages && npm run format:pages:check",
|
||||||
"lint:pages": "npm run lint --workspace=status-page",
|
"lint:pages": "npm run lint --workspace=status-page",
|
||||||
"lint:pages:fix": "npm run lint:fix --workspace=status-page",
|
"lint:pages:fix": "npm run lint:fix --workspace=status-page",
|
||||||
|
|||||||
+2
-2
@@ -11,7 +11,7 @@ vi.mock('cloudflare:workers', () => ({
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
// Mock the auth module
|
// Mock the auth module
|
||||||
vi.mock('../status-page/src/lib/auth.js', () => ({
|
vi.mock('./lib/auth.js', () => ({
|
||||||
checkAuth: vi.fn().mockResolvedValue(undefined),
|
checkAuth: vi.fn().mockResolvedValue(undefined),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
@@ -62,7 +62,7 @@ describe('worker fetch handler', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should return 401 when auth fails', async () => {
|
it('should return 401 when auth fails', async () => {
|
||||||
const { checkAuth } = await import('../status-page/src/lib/auth.js');
|
const { checkAuth } = await import('./lib/auth.js');
|
||||||
vi.mocked(checkAuth).mockResolvedValueOnce(
|
vi.mocked(checkAuth).mockResolvedValueOnce(
|
||||||
new Response('Unauthorized', {
|
new Response('Unauthorized', {
|
||||||
status: 401,
|
status: 401,
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
import { checkAuth } from '../status-page/src/lib/auth.js';
|
import { checkAuth } from './lib/auth.js';
|
||||||
import { handleAggregation } from './aggregation.js';
|
import { handleAggregation } from './aggregation.js';
|
||||||
import { executeDnsCheck } from './checks/dns.js';
|
import { executeDnsCheck } from './checks/dns.js';
|
||||||
import { executeHttpCheck } from './checks/http.js';
|
import { executeHttpCheck } from './checks/http.js';
|
||||||
|
|||||||
@@ -10,11 +10,6 @@ const unauthorizedResponse = (): Response =>
|
|||||||
headers: { 'WWW-Authenticate': 'Basic realm="Status Page"' },
|
headers: { 'WWW-Authenticate': 'Basic realm="Status Page"' },
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
|
||||||
* Timing-safe string comparison using SHA-256 hashing.
|
|
||||||
* Hashing both values to a fixed size prevents leaking length information.
|
|
||||||
* Uses constant-time byte comparison to prevent timing side-channel attacks.
|
|
||||||
*/
|
|
||||||
async function timingSafeCompare(a: string, b: string): Promise<boolean> {
|
async function timingSafeCompare(a: string, b: string): Promise<boolean> {
|
||||||
const encoder = new TextEncoder();
|
const encoder = new TextEncoder();
|
||||||
const [hashA, hashB] = await Promise.all([
|
const [hashA, hashB] = await Promise.all([
|
||||||
@@ -25,7 +20,6 @@ async function timingSafeCompare(a: string, b: string): Promise<boolean> {
|
|||||||
const viewA = new Uint8Array(hashA);
|
const viewA = new Uint8Array(hashA);
|
||||||
const viewB = new Uint8Array(hashB);
|
const viewB = new Uint8Array(hashB);
|
||||||
|
|
||||||
// Constant-time comparison: always check every byte
|
|
||||||
let mismatch = 0;
|
let mismatch = 0;
|
||||||
for (let i = 0; i < viewA.length; i++) {
|
for (let i = 0; i < viewA.length; i++) {
|
||||||
mismatch |= viewA[i] ^ viewB[i];
|
mismatch |= viewA[i] ^ viewB[i];
|
||||||
Reference in New Issue
Block a user