feat: initial public release (MAESTRO)
This commit is contained in:
@@ -0,0 +1,95 @@
|
||||
import { describe, it, expect, beforeEach } from 'vitest';
|
||||
import type { AuditInput } from '../db/browser-session-repo.js';
|
||||
import { assertProfileOwner } from './browser-session-auth.js';
|
||||
|
||||
interface FakeRepo {
|
||||
audit: (input: AuditInput) => void;
|
||||
rows: AuditInput[];
|
||||
}
|
||||
|
||||
function makeFakeRepo(): FakeRepo {
|
||||
const rows: AuditInput[] = [];
|
||||
return {
|
||||
rows,
|
||||
audit(input: AuditInput) {
|
||||
rows.push(input);
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
describe('assertProfileOwner — fail-closed owner enforcement', () => {
|
||||
let fake: FakeRepo;
|
||||
|
||||
beforeEach(() => {
|
||||
fake = makeFakeRepo();
|
||||
});
|
||||
|
||||
it('passes when job.ownerId equals profile.ownerId', () => {
|
||||
expect(() =>
|
||||
assertProfileOwner(
|
||||
{ id: 7, ownerId: 'user-a' },
|
||||
{ id: 'job-1', ownerId: 'user-a' },
|
||||
fake,
|
||||
),
|
||||
).not.toThrow();
|
||||
expect(fake.rows.length).toBe(0);
|
||||
});
|
||||
|
||||
it('throws and audits when job.ownerId is null (legacy / dev-mode jobs)', () => {
|
||||
expect(() =>
|
||||
assertProfileOwner(
|
||||
{ id: 7, ownerId: 'user-a' },
|
||||
{ id: 'job-1', ownerId: null },
|
||||
fake,
|
||||
),
|
||||
).toThrow('Browser session profile owner mismatch');
|
||||
expect(fake.rows).toHaveLength(1);
|
||||
expect(fake.rows[0]).toMatchObject({
|
||||
actorUserId: null,
|
||||
ownerId: 'user-a',
|
||||
profileId: 7,
|
||||
action: 'use',
|
||||
result: 'error',
|
||||
jobId: 'job-1',
|
||||
});
|
||||
expect(fake.rows[0]!.reason).toContain('job.owner=null');
|
||||
expect(fake.rows[0]!.reason).toContain('profile.owner=user-a');
|
||||
});
|
||||
|
||||
it('throws and audits when job.ownerId is undefined', () => {
|
||||
expect(() =>
|
||||
assertProfileOwner(
|
||||
{ id: 7, ownerId: 'user-a' },
|
||||
{ id: 'job-2', ownerId: undefined },
|
||||
fake,
|
||||
),
|
||||
).toThrow('Browser session profile owner mismatch');
|
||||
expect(fake.rows).toHaveLength(1);
|
||||
expect(fake.rows[0]!.reason).toContain('job.owner=null');
|
||||
});
|
||||
|
||||
it('throws and audits when job.ownerId is empty string', () => {
|
||||
expect(() =>
|
||||
assertProfileOwner(
|
||||
{ id: 7, ownerId: 'user-a' },
|
||||
{ id: 'job-3', ownerId: '' },
|
||||
fake,
|
||||
),
|
||||
).toThrow('Browser session profile owner mismatch');
|
||||
expect(fake.rows).toHaveLength(1);
|
||||
});
|
||||
|
||||
it('throws and audits when job.ownerId differs from profile.ownerId', () => {
|
||||
expect(() =>
|
||||
assertProfileOwner(
|
||||
{ id: 9, ownerId: 'user-a' },
|
||||
{ id: 'job-4', ownerId: 'user-b' },
|
||||
fake,
|
||||
),
|
||||
).toThrow('Browser session profile owner mismatch');
|
||||
expect(fake.rows).toHaveLength(1);
|
||||
expect(fake.rows[0]!.reason).toContain('job.owner=user-b');
|
||||
expect(fake.rows[0]!.reason).toContain('profile.owner=user-a');
|
||||
expect(fake.rows[0]!.actorUserId).toBe('user-b');
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user