Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 0 additions & 6 deletions packages/core/src/utils/metadata-activation-store.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,6 @@ const TABLE = 'sys_metadata_activation';
* gate then reports the matcher UNJUDGED, and unjudged is never treated as
* passing.
*/
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function matches(row: any, where: any): boolean {
return Object.entries(where ?? {}).every(([k, v]) => {
// Equality ONLY, and a loud REFUSAL for anything else rather than a
Expand Down Expand Up @@ -84,22 +83,17 @@ function matches(row: any, where: any): boolean {
* read by `metadata_type` and a double that answered every row regardless would
* pin nothing about the discriminator — which is this file's whole subject.
*/
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function makeStoreEngine(rows: any[] = []) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const calls: Array<{ op: string; object: string; data?: any; options?: any }> = [];
const engine = {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
find: vi.fn(async (object: string, options?: any) => {
calls.push({ op: 'find', object, options });
return rows.filter((r) => matches(r, options?.where));
}),
// eslint-disable-next-line @typescript-eslint/no-explicit-any
insert: vi.fn(async (object: string, data: any, options?: any) => {
calls.push({ op: 'insert', object, data, options });
return { id: 'row_new', ...data };
}),
// eslint-disable-next-line @typescript-eslint/no-explicit-any
update: vi.fn(async (object: string, data: any, options?: any) => {
// Routed through the producer's OWN dispatch predicate, so this
// fake cannot be looser than the engine it stands in for — #4434
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,11 +86,9 @@ function makeEngine(seed: MemberRow[] = []) {
return {
rows,
insert,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
find: vi.fn(async (model: string, q: any) =>
model === 'sys_member' ? rows.filter((r) => match(r, q?.where)).slice(0, q?.limit ?? 100) : [],
),
// eslint-disable-next-line @typescript-eslint/no-explicit-any
findOne: vi.fn(async (model: string, q: any) =>
{
assertEngineFindOnePredicate(model, q);
Expand All @@ -107,26 +105,21 @@ interface ManagerOpts {
membershipPolicy?: 'auto' | 'invite-only';
/** What `tenancy.defaultOrgId()` answers. `null` = no unambiguous target. */
defaultOrgId?: string | null;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
databaseHooks?: any;
}

// eslint-disable-next-line @typescript-eslint/no-explicit-any
function hooksFor(opts: ManagerOpts): any {
const manager = new AuthManager({
secret: 'test-secret-at-least-32-chars-long',
baseUrl: 'http://localhost:3000',
dataEngine: opts.engine,
...(opts.membershipPolicy ? { membershipPolicy: opts.membershipPolicy } : {}),
getTenancy: () => ({ defaultOrgId: async () => opts.defaultOrgId ?? null }),
// eslint-disable-next-line @typescript-eslint/no-explicit-any
} as any);
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const hooks = (manager as any).composeDatabaseHooks(opts.databaseHooks);
// What the adapter's `create` does for a `sys_user` row inside the creating
// request (`onRecordCreated`; the real wiring is pinned in
// `user-created-in-request.test.ts`).
// eslint-disable-next-line @typescript-eslint/no-explicit-any
hooks.__stageCreated = (request: unknown, userId: string) => (manager as any).stageUserCreatedInRequest(request, userId);
return hooks;
}
Expand All @@ -136,7 +129,6 @@ function hooksFor(opts: ManagerOpts): any {
* session minted inside ONE endpoint context (the request), and
* `user.create.after` is deferred past both. Returns the session hook's result.
*/
// eslint-disable-next-line @typescript-eslint/no-explicit-any
async function firstSessionOfCreation(hooks: any, session: Record<string, unknown> = { userId: USER }): Promise<any> {
const request = {};
hooks.__stageCreated(request, USER);
Expand Down Expand Up @@ -251,7 +243,6 @@ describe("[#8247 rule 2] a user's FIRST session settles the membership before re

it('the HOST session hook still chains first and still wins', async () => {
const engine = makeEngine();
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const hostHook = vi.fn(async (session: any) => ({
data: { ...session, activeOrganizationId: 'org_host' },
}));
Expand All @@ -274,7 +265,6 @@ describe("[#8247 rule 2] a user's FIRST session settles the membership before re
find: vi.fn(async () => { throw new Error('db down'); }),
insert: vi.fn(async () => { throw new Error('db down'); }),
};
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const hooks = hooksFor({ engine: engine as any, defaultOrgId: DEFAULT_ORG });
const result = await firstSessionOfCreation(hooks);
expect(result?.data?.activeOrganizationId).toBeUndefined();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,6 @@ describe('the resolved options reach the constructed plugin (#7001)', () => {
if (name === 'manifest') return { register() {} };
return undefined;
},
// eslint-disable-next-line @typescript-eslint/no-explicit-any
} as any);
return services.get('security.fallbackPermissionSet');
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,9 +90,7 @@ async function boot(
},
};
const plugin = new SecurityPlugin({ fallbackPermissionSet: 'member_default' });
// eslint-disable-next-line @typescript-eslint/no-explicit-any
await plugin.init(ctx as any);
// eslint-disable-next-line @typescript-eslint/no-explicit-any
await plugin.start(ctx as any);
return { plugin, logger };
}
Expand All @@ -103,7 +101,6 @@ describe('[ADR-0131 D7] plugin-security reads no platformGlobalObjects — the s
{ sys_widget_registry: walledSchema('sys_widget_registry') },
{ entitlement: { platformGlobalObjects: ['sys_widget_registry'] } },
);
// eslint-disable-next-line @typescript-eslint/no-explicit-any
expect(await (plugin as any).getReadFilter('sys_widget_registry', MEMBER_CTX)).toEqual({
organization_id: 'org-1',
});
Expand All @@ -115,7 +112,6 @@ describe('[ADR-0131 D7] plugin-security reads no platformGlobalObjects — the s
{ entitlement: { platformGlobalObjects: ['sys_widget_registry'] }, tenancy: { posture: 'group' } },
);
const groupCtx = { ...MEMBER_CTX, accessible_org_ids: ['org-1', 'org-2'] };
// eslint-disable-next-line @typescript-eslint/no-explicit-any
expect(await (plugin as any).getReadFilter('sys_widget_registry', groupCtx)).toEqual({
organization_id: { $in: ['org-1', 'org-2'] },
});
Expand All @@ -126,7 +122,6 @@ describe('[ADR-0131 D7] plugin-security reads no platformGlobalObjects — the s
{ sys_widget_registry: walledSchema('sys_widget_registry') },
{ entitlement: { platformGlobalObjects: ['sys_widget_registry'] } },
);
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const walled = await (plugin as any).computeWriteTenantCheckFilter(
[PLAIN_MEMBER], 'sys_widget_registry', 'insert', NO_ORG_CTX,
);
Expand All @@ -138,14 +133,11 @@ describe('[ADR-0131 D7] plugin-security reads no platformGlobalObjects — the s
sys_widget_registry: plannedSchema('sys_widget_registry'),
crm_task: walledSchema('crm_task'),
});
// eslint-disable-next-line @typescript-eslint/no-explicit-any
expect(await (plugin as any).getReadFilter('sys_widget_registry', MEMBER_CTX)).toBeUndefined();
// eslint-disable-next-line @typescript-eslint/no-explicit-any
expect(await (plugin as any).computeWriteTenantCheckFilter(
[PLAIN_MEMBER], 'sys_widget_registry', 'insert', NO_ORG_CTX,
)).toBeNull();
// CONTROL — a sibling on the same deployment walls as today.
// eslint-disable-next-line @typescript-eslint/no-explicit-any
expect(await (plugin as any).getReadFilter('crm_task', MEMBER_CTX)).toEqual({ organization_id: 'org-1' });
});

Expand All @@ -154,9 +146,7 @@ describe('[ADR-0131 D7] plugin-security reads no platformGlobalObjects — the s
{ sys_widget_registry: walledSchema('sys_widget_registry'), crm_task: walledSchema('crm_task') },
{ entitlement: { platformGlobalObjects: ['sys_widget_registry'] }, tenancy: { posture: 'single' } },
);
// eslint-disable-next-line @typescript-eslint/no-explicit-any
expect(await (plugin as any).getReadFilter('sys_widget_registry', MEMBER_CTX)).toBeUndefined();
// eslint-disable-next-line @typescript-eslint/no-explicit-any
expect(await (plugin as any).getReadFilter('crm_task', MEMBER_CTX)).toBeUndefined();
});
});
Expand All @@ -167,7 +157,6 @@ describe('[#12699] refusals: this plugin warns only for the key it reads', () =>
{ sys_widget_registry: walledSchema('sys_widget_registry') },
{ entitlement: { platformGlobalObjects: 'sys_widget_registry' } },
);
// eslint-disable-next-line @typescript-eslint/no-explicit-any
await (plugin as any).getReadFilter('sys_widget_registry', MEMBER_CTX);
const warned = logger.warn.mock.calls.map((c) => String(c[0]));
expect(warned.filter((m) => m.includes('org-scoping entitlement key'))).toEqual([]);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,7 @@ async function bootWithSchema(schema: Record<string, unknown>, opts: { tenancy?:
},
};
const plugin = new SecurityPlugin({ fallbackPermissionSet: 'member_default' });
// eslint-disable-next-line @typescript-eslint/no-explicit-any
await plugin.init(ctx as any);
// eslint-disable-next-line @typescript-eslint/no-explicit-any
await plugin.start(ctx as any);
return plugin;
}
Expand All @@ -102,7 +100,6 @@ const federatedSchema = (extra: Record<string, unknown> = {}) => ({
describe('[#7835] Layer 0 vs federated (external) objects', () => {
it('federated object with the INJECTED anchor: no organization_id predicate under `isolated`', async () => {
const plugin = await bootWithSchema(federatedSchema());
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const filter = await (plugin as any).getReadFilter('ext_customer', MEMBER_CTX);
// No Layer 1 policies and no Layer 0 contribution → nothing to AND at all.
expect(filter).toBeUndefined();
Expand All @@ -114,7 +111,6 @@ describe('[#7835] Layer 0 vs federated (external) objects', () => {
// suppression must hold — otherwise the fix would cover one posture and leave
// the other emitting `organization_id IN (…)` against a table without it.
const plugin = await bootWithSchema(federatedSchema(), { tenancy: { posture: 'group' } });
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const filter = await (plugin as any).getReadFilter('ext_customer', {
...MEMBER_CTX,
accessible_org_ids: ['org-1', 'org-2'],
Expand All @@ -135,7 +131,6 @@ describe('[#7835] Layer 0 vs federated (external) objects', () => {
...REMOTE_COLUMNS,
},
});
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const filter = await (plugin as any).getReadFilter('ext_customer', MEMBER_CTX);
expect(filter).toEqual({ organization_id: 'org-1' });
});
Expand All @@ -147,7 +142,6 @@ describe('[#7835] Layer 0 vs federated (external) objects', () => {
name: 'task',
fields: { organization_id: { ...TENANT_SCOPE_FIELD_DEF }, ...REMOTE_COLUMNS },
});
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const filter = await (plugin as any).getReadFilter('task', MEMBER_CTX);
expect(filter).toEqual({ organization_id: 'org-1' });
});
Expand All @@ -159,7 +153,6 @@ describe('[#7835] Layer 0 vs federated (external) objects', () => {
// so there was never isolation here to lose. Object-level CRUD is still the
// gate, and a caller without read permission is refused before this point.
const plugin = await bootWithSchema(federatedSchema());
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const filter = await (plugin as any).getReadFilter('ext_customer', { ...MEMBER_CTX, tenantId: undefined });
expect(filter).toBeUndefined();
});
Expand Down Expand Up @@ -196,9 +189,7 @@ describe('[#7835] Layer 0 vs federated (external) objects', () => {
},
};
const plugin = new SecurityPlugin({ fallbackPermissionSet: 'member_default' });
// eslint-disable-next-line @typescript-eslint/no-explicit-any
await plugin.init(ctx as any); await plugin.start(ctx as any);
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const filter = await (plugin as any).getReadFilter('ext_customer', MEMBER_CTX);
// Layer 0 gone, Layer 1's authored predicate intact — no `$and`, no org column.
expect(filter).toEqual({ region: 'org-1' });
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,22 +117,18 @@ async function boot(opts: BootOpts = {}) {
},
};
const plugin = new SecurityPlugin({ fallbackPermissionSet: opts.fallback ?? 'member_default' });
// eslint-disable-next-line @typescript-eslint/no-explicit-any
await plugin.init(ctx as any);
// eslint-disable-next-line @typescript-eslint/no-explicit-any
await plugin.start(ctx as any);
return {
plugin,
warn,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
readFilter: (object: string, context: any) => (plugin as any).getReadFilter(object, context),
// [#20013] The terminal stands in for the engine, which runs the installed
// `postHookWriteImageCheck` on an INSERT's rows once its `beforeInsert`
// chain has run — here (no hooks) the rows as sent. The Layer 0 tenant wall
// installs that seam on every insert it walls, and a terminal that skipped
// it would be refused fail-closed. Only the insert path is modelled: every
// walled write in this file that reaches the terminal is an insert.
// eslint-disable-next-line @typescript-eslint/no-explicit-any
run: async (opCtx: any) => {
await middleware!(opCtx, async () => {
const seam = opCtx.postHookWriteImageCheck;
Expand All @@ -156,7 +152,6 @@ const ORG_BOUND = { userId: 'u1', tenantId: 'org-1', positions: [], permissions:
* not: the sibling forge guard is also `PERMISSION_DENIED`/403, and any 403 at
* all satisfies the first two.
*/
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function expectConformingRefusal(err: any, opts: { principal?: 'session' | 'delegator' } = {}) {
expect(err, 'the write was not refused at all').toBeDefined();
expect(err.code).toBe('PERMISSION_DENIED');
Expand All @@ -174,10 +169,8 @@ function expectConformingRefusal(err: any, opts: { principal?: 'session' | 'dele
expect(err.developerMessage).toMatch(/ADR-0123 D2/);
}

// eslint-disable-next-line @typescript-eslint/no-explicit-any
async function refusalFrom(run: (opCtx: any) => Promise<unknown>, opCtx: unknown): Promise<any> {
try {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
await run(opCtx as any);
return undefined;
} catch (e) {
Expand Down Expand Up @@ -399,7 +392,6 @@ describe('[ADR-0123 D2] tenant-scoped READS with no active organization resolve
// would be `undefined` (unrestricted) and an ordinary wall would be
// `organization_id = …`; both are different verdicts from this one.
expect(filter).toEqual(RLS_DENY_FILTER);
// eslint-disable-next-line @typescript-eslint/no-explicit-any
expect(matchesFilterCondition(ROW as any, filter as any)).toBe(false);
});

Expand All @@ -411,7 +403,6 @@ describe('[ADR-0123 D2] tenant-scoped READS with no active organization resolve
const h = await boot();
const filter = await h.readFilter('task', { isSystem: true, userId: 'sys', positions: [], permissions: [] });
expect(filter).toBeUndefined(); // no scoping imposed at all
// eslint-disable-next-line @typescript-eslint/no-explicit-any
expect(matchesFilterCondition(ROW as any, (filter ?? {}) as any)).toBe(true);
});

Expand All @@ -422,7 +413,6 @@ describe('[ADR-0123 D2] tenant-scoped READS with no active organization resolve
const h = await boot();
const filter = await h.readFilter('task', { ...ORG_BOUND });
expect(filter).toEqual({ organization_id: 'org-1' });
// eslint-disable-next-line @typescript-eslint/no-explicit-any
expect(matchesFilterCondition(ROW as any, filter as any)).toBe(true);
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,6 @@ describe('default permission sets carry the managed denies (static baseline)', (
describe('sys_invitation is row-scoped to its addressee (#8095)', () => {
const SELF_PREDICATE = 'email == current_user.email';

// eslint-disable-next-line @typescript-eslint/no-explicit-any
const policiesFor = (setName: string, object: string): any[] =>
(setByName(setName)?.rowLevelSecurity ?? []).filter((p: any) => p.object === object);

Expand Down Expand Up @@ -297,7 +296,6 @@ describe('sys_invitation is row-scoped to its addressee (#8095)', () => {
* they have now. So it is pinned here, structurally, next to the declaration.
*/
describe('sys_comment delete is moderation-shaped, not ownership-shaped (#8839)', () => {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const policiesFor = (setName: string, object: string): any[] =>
(setByName(setName)?.rowLevelSecurity ?? []).filter((p: any) => p.object === object);

Expand Down Expand Up @@ -367,7 +365,6 @@ describe('sys_comment_reaction delete is ownership-shaped (#22566)', () => {
it('no shipped set carries a row-level policy on sys_comment_reaction', () => {
expect(defaultPermissionSets.length).toBeGreaterThanOrEqual(6);
for (const set of defaultPermissionSets) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const scoped = (set.rowLevelSecurity ?? []).filter((p: any) => p.object === 'sys_comment_reaction');
expect(scoped, `${set.name} sys_comment_reaction policies`).toEqual([]);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,9 +113,7 @@ async function boot(opts: {
},
};
const plugin = new SecurityPlugin({ fallbackPermissionSet: 'member_default' });
// eslint-disable-next-line @typescript-eslint/no-explicit-any
await plugin.init(ctx as any);
// eslint-disable-next-line @typescript-eslint/no-explicit-any
await plugin.start(ctx as any);
return { plugin, findOne, warn };
}
Expand All @@ -131,7 +129,6 @@ const sessionCtx = (over: Record<string, unknown> = {}) => ({
});

const readFilter = (plugin: unknown, ctx: unknown) =>
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(plugin as any).getReadFilter('task', ctx);

const OLD_OWNER = process.env.OS_PLATFORM_OWNER_EMAIL;
Expand Down Expand Up @@ -266,12 +263,10 @@ describe('[#12974] the bypass lifts ONLY Layer 0', () => {
users: { u_owner: { id: 'u_owner', email: OWNER_EMAIL, email_verified: true } },
});
// Org-carrying owner write: the equality wall stands.
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const owner = await (plugin as any).computeWriteTenantCheckFilter([PLAIN_MEMBER], 'task', 'update', sessionCtx());
expect(owner).toEqual({ organization_id: 'org-1' });
// Org-LESS owner write: the deny sentinel stands — this is the exact
// verdict the ADR-0123 D2 refusal derives its 403 from.
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const ownerOrgless = await (plugin as any).computeWriteTenantCheckFilter(
[PLAIN_MEMBER],
'task',
Expand All @@ -280,7 +275,6 @@ describe('[#12974] the bypass lifts ONLY Layer 0', () => {
);
expect(ownerOrgless).toEqual({ ...RLS_DENY_FILTER });
// Everyone else: unchanged, same wall.
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const member = await (plugin as any).computeWriteTenantCheckFilter(
[PLAIN_MEMBER],
'task',
Expand All @@ -302,7 +296,6 @@ describe('[#12974] audit — the ruled floor', () => {
await readFilter(plugin, sessionCtx({ userId: 'u_m', email: 'member@corp.example' }));
expect(bypassEvents()).toHaveLength(0);
// Owner WRITE: no bypass happens, so no event may claim one did.
// eslint-disable-next-line @typescript-eslint/no-explicit-any
await (plugin as any).computeWriteTenantCheckFilter([PLAIN_MEMBER], 'task', 'update', sessionCtx());
expect(bypassEvents()).toHaveLength(0);
await readFilter(plugin, sessionCtx());
Expand Down
Loading
Loading