import assert from "node:assert/strict"; import type { AccessFieldsDTO, AccessItemDTO, CompanyDTO } from "@metis/companies/common"; import { AccessResponseSchema } from "@metis/companies/common"; export async function verifyAccess( request: (path: string, body?: unknown, origin?: string, token?: string) => Promise, company: CompanyDTO, other: CompanyDTO ) { const base = `/access/${company.id}`; async function create(scope: string, values: AccessFieldsDTO) { const response = await request(`/access/${scope}`, { values }); assert.equal(response.status, 201, JSON.stringify(await response.clone().json())); const result = AccessResponseSchema.parse(await response.json()); const item = result.items.at(-1); assert.ok(item); assert.equal(item.values.kind, values.kind); assert.equal(item.id[14], "7"); assert.equal(item.history.length, 1); return item; } async function update(item: AccessItemDTO, values: AccessFieldsDTO) { const response = await request(`${base}/${item.id}/update`, { values }); assert.equal(response.status, 200, JSON.stringify(await response.clone().json())); return AccessResponseSchema.parse(await response.json()); } const system = await create("global", { kind: "system", name: "Directorio", active: true }); const resourceType = await create("global", { kind: "resource_type", name: "Carpeta", active: true, }); const permission = await create("global", { kind: "permission", name: "Modificar", description: null, resourceTypeId: resourceType.id, active: true, }); const template = await create("global", { kind: "template", name: "Administración", description: "Acceso a documentos", systemId: system.id, active: true, }); assert.equal( (await request(base, { values: { kind: "system", name: " DIRECTORIO ", active: false } })) .status, 409 ); assert.equal( ( await request(base, { values: { kind: "system", name: "Zoom", active: true, password: "secret" }, }) ).status, 400 ); assert.equal( ( await request( base, { values: { kind: "system", name: "Zoom", active: true } }, "https://wrong.example" ) ).status, 403 ); assert.equal( ( await request( base, { values: { kind: "system", name: "Zoom", active: true } }, undefined, "wrong" ) ).status, 403 ); await create(company.id, { kind: "system", name: "ERP propio", active: true }); assert.equal( ( await request("/access/global", { values: { kind: "system", name: "ERP PROPIO", active: true }, }) ).status, 409 ); const environment = await create(company.id, { kind: "environment", name: "Oficina", systemId: system.id, active: true, }); const otherEnvironment = await create(other.id, { kind: "environment", name: "Oficina", systemId: system.id, active: true, }); const accountValues: AccessFieldsDTO = { kind: "account", systemId: system.id, environmentId: environment.id, login: "ana", usage: "personal", active: true, expiresOn: null, notes: null, }; const account = await create(company.id, accountValues); assert.equal((await request(base, { values: accountValues })).status, 409); assert.equal( ( await request(base, { values: { ...accountValues, systemId: system.id.toUpperCase(), environmentId: environment.id.toUpperCase(), }, }) ).status, 409 ); assert.equal( ( await request(base, { values: { ...accountValues, login: "foreign", environmentId: otherEnvironment.id }, }) ).status, 409 ); assert.equal( ( await request(`${base}/${account.id}/update`, { values: { ...accountValues, usage: "shared" }, }) ).status, 409 ); const renamed = { ...accountValues, login: "ana.garcia" }; const changed = await update(account, renamed); assert.equal(changed.items.find((item) => item.id === account.id)?.history.length, 2); const repeated = await update(account, renamed); assert.equal(repeated.items.find((item) => item.id === account.id)?.history.length, 2); const person = company.people.find((item) => item.active); assert.ok(person); const relationValues: AccessFieldsDTO = { kind: "account_person", accountId: account.id, personId: person.id, startDate: "2026-01-01", endDate: null, configuration: "configured", }; const relation = await create(company.id, relationValues); assert.equal((await request(base, { values: relationValues })).status, 409); const foreignPerson = other.people[0]; if (foreignPerson) { assert.equal( (await request(base, { values: { ...relationValues, personId: foreignPerson.id } })).status, 409 ); } const groupValues: AccessFieldsDTO = { kind: "group", name: "Administración", identifier: "GG_ADMIN", systemId: system.id, environmentId: environment.id, templateId: template.id, description: "Documentos", active: true, }; const group = await create(company.id, groupValues); const membershipValues: AccessFieldsDTO = { kind: "membership", accountId: account.id, groupId: group.id, startDate: "2026-01-01", endDate: null, configuration: "configured", }; const membership = await create(company.id, membershipValues); const resource = await create(company.id, { kind: "resource", name: "Documentos", resourceTypeId: resourceType.id, systemId: null, environmentId: null, reference: "\\\\NAS\\Administracion", notes: null, active: true, }); const grantValues: AccessFieldsDTO = { kind: "grant", resourceId: resource.id, permissionId: permission.id, accountId: null, groupId: group.id, startDate: "2026-01-01", endDate: null, configuration: "configured", }; const grant = await create(company.id, grantValues); const needValues: AccessFieldsDTO = { kind: "need", resourceId: resource.id, personId: person.id, permissionIds: [permission.id], startDate: "2026-01-01", endDate: null, notes: null, }; const need = await create(company.id, needValues); let response = AccessResponseSchema.parse(await (await request(base)).json()); assert.equal(response.coverage.find((item) => item.needId === need.id)?.covered, false); assert.ok( response.reviews.some((item) => item.itemId === grant.id && item.reason === "unjustified") ); await create(company.id, { kind: "coverage", needId: need.id, grantId: grant.id, accountPersonId: relation.id, membershipId: membership.id, startDate: "2026-01-01", endDate: null, }); response = AccessResponseSchema.parse(await (await request(base)).json()); assert.equal(response.coverage.find((item) => item.needId === need.id)?.covered, true); assert.equal( response.reviews.some((item) => item.itemId === grant.id && item.reason === "unjustified"), false ); const awaitingConfiguration = await update(relation, { ...relationValues, configuration: "pending", }); assert.equal( awaitingConfiguration.coverage.find((item) => item.needId === need.id)?.covered, false ); assert.equal( awaitingConfiguration.reviews.some( (item) => item.itemId === grant.id && item.reason === "unjustified" ), false ); await update(relation, relationValues); const readPermission = await create("global", { kind: "permission", name: "Lectura", description: null, resourceTypeId: resourceType.id, active: true, }); const differentNeed = await update(need, { ...needValues, permissionIds: [readPermission.id] }); assert.equal(differentNeed.coverage.find((item) => item.needId === need.id)?.covered, false); assert.ok( differentNeed.reviews.some((item) => item.itemId === grant.id && item.reason === "unjustified") ); await update(need, needValues); const closed = await update(membership, { ...membershipValues, endDate: "2026-10-03", configuration: "removal_pending", }); assert.equal(closed.coverage.find((item) => item.needId === need.id)?.covered, false); assert.ok( closed.reviews.some( (item) => item.itemId === membership.id && item.reason === "pending_removal" ) ); const removed = await update(membership, { ...membershipValues, endDate: "2026-10-03", configuration: "removed", }); assert.equal( removed.reviews.some( (item) => item.itemId === membership.id && item.reason === "pending_removal" ), false ); assert.equal(removed.items.find((item) => item.id === membership.id)?.history.length, 3); assert.equal( removed.items .find((item) => item.id === membership.id) ?.history.every((item) => Boolean(item.actorId)), true ); const expired = await update(account, { ...renamed, expiresOn: "2000-01-01" }); assert.ok( expired.reviews.some((item) => item.itemId === account.id && item.reason === "expired") ); assert.equal( (await request(base, { values: { ...membershipValues, startDate: "2026-10-03" } })).status, 409 ); const technical = await create(company.id, { ...accountValues, login: "svc-backup", usage: "technical", active: false, expiresOn: "2000-01-01", }); await create(company.id, { ...relationValues, accountId: technical.id, configuration: null }); const otherTechnical = await create(company.id, { ...accountValues, login: "svc-clean", usage: "technical", active: true, }); assert.equal( ( await request(base, { values: { ...relationValues, accountId: otherTechnical.id, configuration: "configured" }, }) ).status, 400 ); const shared = await create(company.id, { ...accountValues, login: "shared", usage: "shared" }); const sharedResponse = AccessResponseSchema.parse(await (await request(base)).json()); assert.ok( sharedResponse.reviews.some((item) => item.itemId === shared.id && item.reason === "incomplete") ); const concurrent = await Promise.all([ request(base, { values: { ...accountValues, login: "concurrent" } }), request(base, { values: { ...accountValues, login: "concurrent" } }), ]); assert.deepEqual(concurrent.map((item) => item.status).sort(), [201, 409]); const otherScope = AccessResponseSchema.parse( await (await request(`/access/${other.id}`)).json() ); assert.equal( otherScope.items.some((item) => item.id === account.id), false ); assert.equal( otherScope.items.some((item) => item.id === system.id), true ); const global = AccessResponseSchema.parse(await (await request("/access/global")).json()); assert.equal( global.items.every((item) => item.companyId === null), true ); assert.equal( (await request(`/access/${other.id}/${account.id}/update`, { values: renamed })).status, 404 ); }