/** * Per-PC credential controls on PC Details. * * Revoke and allow-reenroll are admin-role routes on the server. The page reads * the credential from the same endpoint state call the liveness chip uses, and * offers the two actions to admins only; every other reader gets the state in * the Endpoint status card, where the server has already redacted the details. * * Asserted against the file text, matching pcDetailRunScripts.spec.js. */ import { describe, it, expect } from 'vitest' import { readFileSync } from 'fs' import { join, dirname } from 'path' import { fileURLToPath } from 'url' const here = dirname(fileURLToPath(import.meta.url)) const source = readFileSync(join(here, 'PCDetail.vue'), 'utf8') // Relative to the staged copy under src/.plugins-staged/, which is what runs. const api = readFileSync(join(here, '..', '..', '..', 'api', 'index.js'), 'utf8') describe('PCDetail credential controls', () => { it('gates the controls on the admin role', () => { expect(source).toMatch(/const canManageCredential = computed\(\(\) => authStore\.isAdmin\)/) expect(source).toMatch(/v-if="canManageCredential && credential"/) }) it('reads the credential from the endpoint state response', () => { const loader = source.slice(source.indexOf('async function loadLiveness')) const body = loader.slice(0, loader.indexOf('\n}\n')) expect(body).toMatch(/credential\.value = state\.credential \|\| null/) }) it('offers revoke only for an enrolled PC and allow only for a blocked one', () => { expect(source).toMatch(/v-if="credential\.state === 'enrolled'"[\s\S]{0,120}credential-revoke/) expect(source).toMatch(/v-if="credential\.reenrollblocked"[\s\S]{0,120}credential-allow/) }) it('offers the keep-from-enrolling option and sends it with the reason', () => { expect(source).toMatch(/v-model="revokeblockreenroll"/) expect(source).toMatch(/Keep this PC from enrolling again/) const handler = source.slice(source.indexOf('async function submitRevokeCredential')) const body = handler.slice(0, handler.indexOf('\n}\n')) expect(body).toMatch(/blockreenroll: revokeblockreenroll\.value/) expect(body).toMatch(/reason: revokereason\.value\.trim\(\)/) }) it('calls the existing enrollment routes', () => { expect(api).toMatch(/`\/endpoints\/enrollment\/assets\/\$\{assetId\}\/revoke`/) expect(api).toMatch(/`\/endpoints\/enrollment\/assets\/\$\{assetId\}\/allow-reenroll`/) expect(api).toMatch(/if \(opts\.blockreenroll\) \{\s*body\.blockreenroll = true/) }) it('confirms before allowing re-enrollment', () => { const handler = source.slice(source.indexOf('async function confirmAllowReenroll')) const body = handler.slice(0, handler.indexOf('\n}\n')) expect(body).toMatch(/if \(!confirm\(/) }) })