@aglyn/plugins-marketplace 1.0.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +14 -14
- package/src/lib/components/listing-detail-editor.component.js +26 -26
- package/src/lib/components/listing-detail-editor.component.js.map +1 -1
- package/src/lib/components/plugin-review-detail.component.js +17 -3
- package/src/lib/components/plugin-review-detail.component.js.map +1 -1
- package/src/lib/components/plugin-reviews-queue.component.js +88 -12
- package/src/lib/components/plugin-reviews-queue.component.js.map +1 -1
- package/src/lib/components/site-starter-review-detail.component.d.ts +115 -0
- package/src/lib/components/site-starter-review-detail.component.js +785 -0
- package/src/lib/components/site-starter-review-detail.component.js.map +1 -0
- package/src/lib/components/starter-picker-shelf.component.d.ts +7 -0
- package/src/lib/components/starter-picker-shelf.component.js +75 -1
- package/src/lib/components/starter-picker-shelf.component.js.map +1 -1
- package/src/lib/hooks/use-starter-answers.d.ts +41 -0
- package/src/lib/hooks/use-starter-answers.js +75 -0
- package/src/lib/hooks/use-starter-answers.js.map +1 -0
- package/src/lib/model/listing-query.d.ts +20 -2
- package/src/lib/model/listing-query.js +55 -0
- package/src/lib/model/listing-query.js.map +1 -1
- package/src/lib/model/plugin-rejection-categories.d.ts +17 -2
- package/src/lib/model/plugin-rejection-categories.js +48 -4
- package/src/lib/model/plugin-rejection-categories.js.map +1 -1
- package/src/lib/model/plugin-review-checklist.d.ts +38 -8
- package/src/lib/model/plugin-review-checklist.js +60 -11
- package/src/lib/model/plugin-review-checklist.js.map +1 -1
- package/src/lib/model/plugin-review-status.d.ts +8 -0
- package/src/lib/model/plugin-review-status.js +34 -0
- package/src/lib/model/plugin-review-status.js.map +1 -1
- package/src/lib/model/starter-category.d.ts +58 -0
- package/src/lib/model/starter-category.js +79 -0
- package/src/lib/model/starter-category.js.map +1 -0
- package/src/lib/model/starter-query.d.ts +27 -0
- package/src/lib/model/starter-query.js +42 -0
- package/src/lib/model/starter-query.js.map +1 -1
- package/src/lib/server/admin-reviews.js +294 -45
- package/src/lib/server/admin-reviews.js.map +1 -1
- package/src/lib/server/publish-plugin.js +46 -4
- package/src/lib/server/publish-plugin.js.map +1 -1
- package/src/lib/server/publish-starter.js +4 -0
- package/src/lib/server/publish-starter.js.map +1 -1
- package/src/lib/server/publisher-review-email.d.ts +5 -0
- package/src/lib/server/publisher-review-email.js +2 -1
- package/src/lib/server/publisher-review-email.js.map +1 -1
- package/src/lib/server/starters.d.ts +4 -1
- package/src/lib/server/starters.js +128 -28
- package/src/lib/server/starters.js.map +1 -1
- package/src/lib/server.js +12 -1
- package/src/lib/server.js.map +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../../libs/plugins/marketplace/src/lib/server/admin-reviews.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n REVOKED_VERSION_REVIEW_STATE,\n revocationWithdrawsReviewedClaim,\n shouldStripVerifiedOnTakedown,\n VERIFIED_STRIPPED_STATUS,\n} from '../model/plugin-review-status'\nimport {\n checkPluginBundle,\n isPluginRevoked,\n newestInstallableVersion,\n isStoredVerdictCurrent,\n nextRevocationState,\n PLUGIN_HOST_ABI_VERSION,\n PLUGIN_VERIFIER_VERSION,\n pluginArtifactPath,\n pluginRequestFromWeb,\n readPluginContributions,\n type PluginRevocation,\n type StoredBundleVerdict,\n} from '@aglyn/aglyn/server'\nimport {\n emailUnverifiedResponse,\n findUserByUidAcrossPools,\n firebaseAdmin,\n isImpersonationSession,\n updateExisting,\n} from '@aglyn/tenant-data-admin'\nimport { invalidIdTokenResponse } from '@aglyn/tenant-data-admin/server/id-token-refusal'\nimport { buildRoute, Route } from '@aglyn/aglyn/server'\nimport {\n outstandingChecklistItems,\n PLUGIN_REVIEW_CHECKLIST,\n} from '../model/plugin-review-checklist'\nimport {\n pluginRejectionCategory,\n rejectionHeadline,\n rejectionInputError,\n} from '../model/plugin-rejection-categories'\nimport { attestationsForBytes } from '../model/publisher-attestation'\nimport { VERIFICATION_DECLINE_COOLDOWN_DAYS } from '../model/listing-verification'\nimport { isPrivateListing } from '../model/listing-visibility'\nimport {\n PUBLISHER_AGREEMENT_VERSION,\n publisherAgreementState,\n} from '../model/publisher-agreement'\nimport { FieldValue } from 'firebase-admin/firestore'\nimport { notifyOrgAdmins } from '@aglyn/tenant-data-admin'\nimport { refreshListingQueryFields } from './listing-query-fields'\nimport { nameSearchNormalizers } from '@aglyn/aglyn/app-utils/name-search'\nimport {\n type ListQueryPlan,\n planListQuery,\n} from '@aglyn/shared-ui-jsx/const/list-query-plan'\nimport { applyListQuery } from '@aglyn/tenant-data-admin/server/list-query'\nimport {\n REVIEW_QUEUE_QUERY,\n type ReviewQueueSection,\n reviewQueueBase,\n reviewQueueStatusClauses,\n} from '../model/listing-query'\n/*\n * The publisher fan-out lives beside the usage-alert one in `_lib` rather\n * than here. Both are multi-recipient platform sends that have to read the\n * platform suppression list before addressing anybody, and that list has to\n * be reachable by a spec that does not drag the admin SDK in behind a route.\n */\nimport { emailPublisher } from './publisher-review-email'\nimport { dropCachesForListing } from './revoke-cache-drop'\nimport { addAdminAudit } from '@aglyn/tenant-data-admin/server/admin-audit-write'\nimport { compareArtifactVersions } from '../model/update-state'\n\n/**\n * Marketplace review queue (AGL-432) — Strapi Market's two-phase review\n * as staff tooling. GET returns plugin listings awaiting review\n * (submitted/in_review) with the static-verifier verdict re-run against\n * the stored artifact (the same AGL-426 checks the publish API enforced —\n * re-run here so a reviewer sees them without trusting the publish-time\n * result). POST moves a listing through the lifecycle:\n *\n * start-review → in_review list → listed (publicly browsable)\n * verify → verified (✅ badge) reject → rejected (+ reason,\n * notification to the publisher)\n *\n * Realm trust stays a SEPARATE, super-staff grant (`admin-trust.ts`) —\n * listing/verifying here never signs anything. Every action lands in\n * adminAudit.\n */\n/** Every id the checklist route will accept (AGL-963). */\nconst REQUIRED_OR_OPTIONAL = new Set(\n PLUGIN_REVIEW_CHECKLIST.map((item) => item.id),\n)\n\nconst ACTIONS: Record<string, string> = {\n 'start-review': 'in_review',\n list: 'listed',\n verify: 'verified',\n reject: 'rejected',\n // Moves BACK down the ladder (AGL-965). Review used to be a one-way\n // ratchet: the only retreats were `reject`, which reads as a verdict on\n // the whole listing and notifies the publisher as such, and takedown,\n // which is the kill switch and stops the plugin in every workspace that\n // already installed it. Neither expresses \"pull it from the marketplace\n // while we look again, without breaking the sites already using it\".\n delist: 'in_review',\n unverify: 'listed',\n}\n\n/*\n * THE WORDS A PUBLISHER READS ABOUT A VERDICT (AGL-3432).\n *\n * The publisher email (`plugin-review-update`) prints only its body, never its\n * subject, and the console feed shows the body under a short title. So every\n * body below opens by naming the plugin, the version when there is one, and\n * what happened to it. A publisher with several plugins cannot tell from\n * \"Your plugin\" which one review means.\n *\n * A private listing never reaches the marketplace (AGL-968), so its copy never\n * says it entered or left it.\n */\n\n/** \"Acme Forms version 1.2.0\", or just the name when no version is known. */\nfunction pluginAndVersion(name: string, version: string): string {\n return version ? `${name} version ${version}` : name\n}\n\n/**\n * Why it was turned down: the category and what to do about it, then the\n * reviewer's comment when there is one (AGL-977).\n *\n * A comment is required only for \"Other\", so every other rejection stands on\n * its category: printing the optional comment alone would leave most\n * rejections with a blank reason and nothing to fix. \"Other\" says nothing by\n * itself, so there the comment is the reason.\n */\nfunction rejectionReasonText(category: string, reason: string): string {\n const picked = pluginRejectionCategory(category)\n const comment = reason.trim()\n if (!picked || picked.requiresComment) return comment\n const because = `${picked.label}. ${picked.guidance}`\n return comment ? `${because}\\n\\nReviewer’s comment: ${comment}` : because\n}\n\n/** The body of a version verdict, for the console notification and the email. */\nfunction versionVerdictBody(input: {\n approving: boolean\n name: string\n version: string\n /** The version new installs receive once this verdict has landed. */\n offeredVersion: string\n /** This approval is what put the listing in the marketplace. */\n listedNow: boolean\n category: string\n reason: string\n liveInstalls: number\n}): string {\n const { name, version, offeredVersion, liveInstalls } = input\n const subject = pluginAndVersion(name, version)\n if (input.approving) {\n // Approving an OLDER version never walks the offer back, so \"now the\n // version new installs receive\" is said only when it became so.\n const offer =\n offeredVersion === version\n ? `It is now the version new installs of ${name} receive. Sites ` +\n 'already running it stay on the version they have until their ' +\n 'owners upgrade.'\n : offeredVersion\n ? `New installs still receive version ${offeredVersion}, the ` +\n 'newest approved version.'\n : ''\n return [\n `${subject} passed review.${offer ? ` ${offer}` : ''}`,\n input.listedNow ? `${name} is now listed in the marketplace.` : '',\n ]\n .filter(Boolean)\n .join('\\n\\n')\n }\n const why = rejectionReasonText(input.category, input.reason)\n return [\n `${subject} was not approved${why ? `: ${why}` : '.'}`,\n `Publishing a new version puts ${name} back in the review queue. The ` +\n 'previously approved version, if any, keeps installing in the meantime.',\n // Pins sitting on these bytes (AGL-1085). The publisher cannot uninstall\n // a version from somebody else's site, so this says what happens rather\n // than telling them to do it.\n liveInstalls > 0\n ? `Version ${version} is still running on ${liveInstalls} ` +\n `site${liveInstalls === 1 ? '' : 's'}. A rejection stops new ` +\n 'installs; it does not remove the version from sites already ' +\n 'running it.'\n : '',\n ]\n .filter(Boolean)\n .join('\\n\\n')\n}\n\n/** The body of a listing verdict, for the console notification and the email. */\nfunction listingVerdictBody(input: {\n action: string\n name: string\n /** The listing's newest bytes, the ones the reviewer read. */\n version: string\n /** The version new installs receive. */\n offeredVersion: string\n isPrivate: boolean\n category: string\n reason: string\n}): string {\n const { name, offeredVersion, isPrivate } = input\n const subject = pluginAndVersion(name, input.version)\n const comment = input.reason.trim()\n const offer = offeredVersion\n ? ` New installs receive version ${offeredVersion}.`\n : ''\n switch (input.action) {\n case 'reject': {\n // A rejection is not a delist, comment or no comment: nobody looks\n // again until the publisher fixes it and sends a new version, so it\n // never borrows the delist's \"while we review it again\".\n const why = rejectionReasonText(input.category, input.reason)\n const where = isPrivate ? 'in review' : 'from the marketplace'\n const meanwhile = isPrivate\n ? 'Sites that already installed it keep working.'\n : `${name} is out of the marketplace while it is rejected; sites ` +\n 'that already installed it keep working.'\n return [\n `${subject} was rejected ${where}${why ? `: ${why}` : '.'}`,\n `${meanwhile} To send it back for review, publish a new version.`,\n ].join('\\n\\n')\n }\n case 'delist':\n return [\n isPrivate\n ? `We moved ${subject} back into review. Sites that already ` +\n 'installed it keep working.'\n : `We removed ${subject} from the marketplace while we review it ` +\n 'again. Sites that already installed it keep working.',\n comment ? `Reviewer’s comment: ${comment}` : '',\n ]\n .filter(Boolean)\n .join('\\n\\n')\n case 'verify':\n return isPrivate\n ? `${name} is now verified.`\n : `${name} is now verified: its marketplace listing shows the ` +\n 'verified badge.'\n default:\n return isPrivate\n ? `${name} passed review. It is a private plugin, so it stays out ` +\n `of the marketplace and only your workspace can install it.${offer}`\n : `${name} passed review and is now listed in the marketplace.${offer}`\n }\n}\n\n/**\n * One listing in full, for the detail page (AGL-959). The index deals in\n * rows; everything a reviewer needs to actually decide — manifest,\n * capabilities, ABI, verifier findings, per-version trust, takedown state —\n * is assembled here rather than smeared across the list payload.\n */\nasync function listingDetail(\n firestore: FirebaseFirestore.Firestore,\n listingId: string,\n requestedVersion?: string,\n): Promise<Response> {\n const listingRef = firestore.collection('marketplaceListings').doc(listingId)\n const snapshot = await listingRef.get()\n const listing = snapshot.data()\n if (!listing) {\n return Response.json({ error: 'Unknown listing' }, { status: 404 })\n }\n\n const versionsSnapshot = await listingRef\n .collection('pluginVersions')\n .orderBy('publishedAt', 'desc')\n .limit(25)\n .get()\n const versions = versionsSnapshot.docs.map((doc) => {\n const publishedAt = doc.get('publishedAt')\n return {\n version: String(doc.get('version') ?? doc.id),\n trust: doc.get('trust') ?? null,\n sha256: String(doc.get('sha256') ?? ''),\n hostAbi: Number(doc.get('manifest.hostAbi')) || null,\n capabilities: doc.get('manifest.capabilities') ?? {},\n // What these bytes declare they contribute (AGL-3116); `null` when the\n // version predates the contract and loads under its default.\n contributes: readPluginContributions(doc.get('manifest.contributes')) ?? null,\n // Declared canvas elements (AGL-1031), for THESE bytes. Publisher copy\n // that renders in the customer's element picker and nowhere on the\n // listing page — so without it here, the `element-metadata` criterion\n // asks a reviewer to check text this page never shows (AGL-2486).\n elements: doc.get('manifest.elements') ?? [],\n publishedAt: publishedAt?.toDate?.()?.toISOString() ?? null,\n // Per-version installs (AGL-1036). \"How many workspaces would a revoke\n // actually hit\" is a per-version question, and the listing total shown\n // elsewhere on this page answers a different one.\n installCount: Number(doc.get('installCount') ?? 0),\n activeInstalls: Number(doc.get('activeInstalls') ?? 0),\n signed: Boolean(doc.get('signature')),\n // The repo as declared for THESE bytes (AGL-1076); absent on versions\n // published before it was collected.\n repositoryUrl: String(doc.get('repositoryUrl') ?? ''),\n reviewState: String(doc.get('reviewState') ?? 'pending'),\n grandfathered: Boolean(doc.get('grandfathered')),\n // Server-side only — used to decide whether the verdict below needs\n // recomputing; stripped before the payload goes out.\n verification: doc.get('verification') ?? null,\n reviewChecklist: doc.get('reviewChecklist') ?? null,\n publisherAttestation: doc.get('publisherAttestation') ?? null,\n }\n })\n\n // Publisher is an ORG since AGL-652 — show the name, not the raw id.\n const publisherId = String(listing.profileId ?? '')\n const publisher = publisherId\n ? await firestore.collection('orgs').doc(publisherId).get()\n : null\n\n // Which terms this publisher is actually under (AGL-1077). A reviewer\n // weighing a takedown, a delist, or a revocation is deciding what we are\n // entitled to do — and that is answered by the agreement the ORG accepted,\n // not by the per-version attestation beside it.\n const publisherProfile = publisherId\n ? await firestore.collection('publisherProfiles').doc(publisherId).get()\n : null\n const acceptance = publisherProfile?.get('publisherAgreement') as\n | { version?: string; acceptedBy?: string; acceptedAt?: { toDate?: () => Date } }\n | undefined\n\n // Kill switch, so the page can say whether the plugin is actually stopped\n // rather than only de-listed (AGL-948).\n const revocation = (\n await firestore.collection('revocations').doc(listingId).get()\n ).data()\n\n // The verifier verdict for the version under review (AGL-426), served\n // from the version doc when it is current (AGL-962).\n //\n // `checkPluginBundle` is pure and the artifact is immutable and\n // content-addressed, so a verdict pinned to {sha256, verifierVersion} is\n // exactly as trustworthy as re-running it — and re-running meant\n // downloading up to a megabyte from Storage on EVERY page view. A stored\n // verdict from an older checker, or for different bytes, is ignored.\n // Which version this page is reviewing (AGL-966). Defaults to the oldest\n // version still awaiting a verdict — that is the work — falling back to\n // the latest when everything is decided. A reviewer can pin any version\n // explicitly; the checklist and verifier verdict follow the selection,\n // because both are statements about specific bytes.\n const pendingFirst = [...versions]\n .reverse()\n .find((entry) => entry.reviewState !== 'approved')\n const reviewVersion =\n (requestedVersion &&\n versions.find((entry) => entry.version === requestedVersion)?.version) ||\n pendingFirst?.version ||\n String(listing.latestVersion ?? '')\n const artifactsBucket = process.env.PLUGIN_ARTIFACTS_BUCKET\n const reviewEntry = versions.find((entry) => entry.version === reviewVersion)\n const reviewSha = reviewEntry?.sha256\n const stored = reviewEntry?.verification as StoredBundleVerdict | undefined\n const storedIsCurrent = isStoredVerdictCurrent(stored, reviewSha ?? '')\n\n let verifier: unknown = storedIsCurrent\n ? {\n ok: stored?.ok,\n problems: stored?.problems ?? [],\n // The per-check summary rides along in the stored verdict (AGL-1087)\n // so the page can show what was checked without re-downloading a\n // megabyte of artifact on every view.\n checks: stored?.checks ?? [],\n }\n : null\n let verifierCached = storedIsCurrent\n if (!storedIsCurrent && artifactsBucket && reviewSha) {\n try {\n const [bytes] = await firebaseAdmin\n .app()\n .storage()\n .bucket(artifactsBucket)\n .file(pluginArtifactPath(listingId, reviewVersion, reviewSha))\n .download()\n // The manifest for THESE bytes, so an undeclared network call is a\n // finding rather than a warning (AGL-964). Read from the version doc,\n // never from the listing — capabilities change between versions.\n const result = checkPluginBundle(bytes.toString('utf8'), {\n declaredNetwork: Array.isArray(reviewEntry?.capabilities?.network)\n ? reviewEntry.capabilities.network.map((origin: unknown) =>\n String(origin),\n )\n : [],\n // Compared, never required: a version published before the contract\n // loads under its default, and review must not refuse it for a rule\n // it was never held to.\n declaredContributions: reviewEntry?.contributes ?? null,\n })\n verifier = result\n // Write it back so this sha is verified at most once platform-wide —\n // covers every listing published before the verdict was persisted at\n // publish time, and any version whose checker has since moved on.\n // Best effort: a failed write costs the next reader a re-run, nothing\n // more, so it must never fail the page.\n await listingRef\n .collection('pluginVersions')\n .doc(reviewVersion)\n .set(\n {\n verification: {\n ok: result.ok,\n problems: result.problems,\n checks: result.checks,\n sha256: reviewSha,\n verifierVersion: PLUGIN_VERIFIER_VERSION,\n checkedAt: FieldValue.serverTimestamp(),\n },\n },\n { merge: true },\n )\n .catch(() => undefined)\n } catch {\n verifier = { error: 'artifact unavailable' }\n verifierCached = false\n }\n }\n\n // Who attested, by name (AGL-969). \"A named publisher said this on a date\"\n // is the half that makes a false attestation actionable, and a raw uid\n // names nobody. Best effort — a deleted account must not blank the page.\n const attestationEntries = Object.values(\n (reviewEntry?.publisherAttestation ?? {}) as Record<\n string,\n { by?: string; at?: { toDate?: () => Date }; sha256?: string }\n >,\n ).filter((entry) => entry?.sha256 === reviewSha)\n const attesterUid = attestationEntries.find((entry) => entry.by)?.by\n const attestedAt =\n attestationEntries.find((entry) => entry.at)?.at?.toDate?.()?.toISOString() ??\n null\n let attestedBy: string | null = attesterUid ?? null\n if (attesterUid) {\n try {\n // Across pools (AGL-1122): an SSO attester is invisible to project-level\n // `getUser`, so this fell through to the catch and the review page named\n // the attester by raw uid — indistinguishable from \"account deleted\".\n const found = await findUserByUidAcrossPools(attesterUid)\n if (found) {\n attestedBy =\n found.record.email ?? found.record.displayName ?? attesterUid\n }\n } catch {\n // Account gone — the uid still identifies the statement.\n }\n }\n\n return Response.json(\n {\n listingId,\n displayName: listing.displayName ?? listingId,\n description: listing.description ?? '',\n // The publisher's ask, so the page can offer Decline beside Verify\n // (AGL-1217). Serialized: `decidedAt`/`requestedAt` are Timestamps and\n // this payload crosses JSON.\n verificationRequest: listing.verificationRequest\n ? {\n state: String(listing.verificationRequest.state ?? ''),\n requestedAt:\n listing.verificationRequest.requestedAt?.toDate?.()?.toISOString() ??\n null,\n declineReason: listing.verificationRequest.declineReason ?? null,\n }\n : null,\n readme: listing.readme ?? '',\n license: listing.license ?? '',\n categories: listing.categories ?? [],\n homepageUrl: listing.homepageUrl ?? '',\n // Prefer what the version under review declared (AGL-1076). The\n // listing carries whatever the most recent publish said, and a repo\n // can move between versions — the link a reviewer opens should be the\n // one attested against the bytes in front of them. Falls back to the\n // listing for versions published before this was collected.\n repositoryUrl: reviewEntry?.repositoryUrl || listing.repositoryUrl || '',\n publisherId,\n publisherName: publisher?.get('name') ?? publisherId,\n publisherSlug: publisher?.get('slug') ?? null,\n reviewStatus: listing.reviewStatus ?? 'submitted',\n rejectionReason: listing.rejectionReason ?? '',\n rejectionCategory: listing.rejectionCategory ?? '',\n priceUsd: Number(listing.priceUsd ?? 0),\n latestVersion: String(listing.latestVersion ?? ''),\n // The version the checklist, verifier verdict and approve/reject\n // actions on this payload refer to.\n reviewVersion,\n activeInstalls: Number(listing.activeInstalls ?? 0),\n hidden: Boolean(listing.hiddenAt),\n hiddenReason: String(listing.hiddenReason ?? ''),\n revoked: Boolean(revocation),\n revokedVersions: revocation?.versions ?? null,\n unpublished: Boolean(listing.deletedAt),\n private: listing.visibility === 'private',\n platformHostAbi: PLUGIN_HOST_ABI_VERSION,\n // Where the bundle bytes actually live (AGL-990). Staff-only payload,\n // and a bucket NAME is not a credential — reaching the object still\n // needs a Google account with access. Without it the page cannot build\n // a Cloud console link, and this bucket does not appear in the Firebase\n // console at all, so a reviewer has no way to find it by hand.\n artifactsBucket: artifactsBucket ?? null,\n versions: versions.map(\n // The rest-strip is the point: `verification`, `reviewChecklist` and\n // `publisherAttestation` are named only so they DO NOT reach the\n // client payload, which is what the disable below is for. The\n // duplicate directive that used to sit above `versions.map(` covered\n // a line with nothing unused on it, and this config treats an\n // unused disable as a failure.\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n ({ verification, reviewChecklist, publisherAttestation, ...entry }) => ({\n ...entry,\n // Per-version kill-switch state (AGL-1085), read through the same\n // helper the loaders use so the page cannot disagree with the\n // runtime about whether these bytes are stopped.\n revoked: isPluginRevoked(\n revocation as PluginRevocation | undefined,\n entry.version,\n ),\n }),\n ),\n // Review checklist for the version under review (AGL-963). Ticks made\n // against different bytes do not count, so a republish starts clean.\n checklist: Object.fromEntries(\n Object.entries(\n (reviewEntry?.reviewChecklist ?? {}) as Record<\n string,\n { by?: string; sha256?: string }\n >,\n )\n .filter(([, entry]) => entry?.sha256 === reviewSha)\n .map(([id, entry]) => [id, { by: entry.by ?? null }]),\n ),\n checklistOutstanding: outstandingChecklistItems(\n reviewEntry?.reviewChecklist as never,\n reviewSha ?? '',\n ),\n // What the publisher stated about THESE bytes (AGL-969). Not a review\n // input — a reviewer still checks everything themselves — but it says\n // what was claimed, so a discrepancy is a documented false statement\n // rather than a difference of opinion. Attestations recorded against\n // other bytes are dropped, exactly like staff ticks.\n attestation: attestationsForBytes(\n reviewEntry?.publisherAttestation as never,\n reviewSha ?? '',\n ),\n attestedBy,\n attestedAt,\n // The publisher agreement this ORG is under (AGL-1077). `current` is\n // computed here rather than shipped as a boolean so the page can say\n // \"on an older version\" — which is a different thing from never\n // having accepted, and matters differently to a takedown decision.\n publisherAgreement: {\n version: acceptance?.version ?? null,\n acceptedAt: acceptance?.acceptedAt?.toDate?.()?.toISOString() ?? null,\n required: PUBLISHER_AGREEMENT_VERSION,\n state: publisherAgreementState(acceptance),\n },\n verifier,\n verifierCached,\n verifierVersion: PLUGIN_VERIFIER_VERSION,\n },\n { status: 200 },\n )\n}\n\n/**\n * Re-derive `latestApprovedVersion` from the versions themselves (AGL-2306).\n *\n * The mirror was written on approval only, with a comment saying it \"only ever\n * moves forward\" — true of approvals, and the reason it is there. What nothing\n * did was move it BACK. A version approved and later rejected on re-review, or\n * killed with the per-version switch, left the listing still advertising it:\n * `host-plugins-card` and `model/update-state` read this field to offer\n * \"Update to vX\", and `install-plugin` would then refuse those exact bytes.\n *\n * Contained, because `install-plugin` recomputes approval live and never\n * trusts this field — no unreviewed or revoked bytes could ship — but it is\n * the AGL-1016 guarantee leaking back out through a badge, which is where\n * AGL-966 came in.\n *\n * Recomputed rather than decremented: \"the newest version that is approved AND\n * not revoked\" is a property of the whole set, and stepping it back one at a\n * time is how a mirror drifts in the other direction.\n *\n * Revoked versions are excluded because the offer has to be installable, and\n * `install-plugin` 409s on a revoked pin. That also makes un-revoking restore\n * the offer, which is why this runs on both revoke and unrevoke.\n *\n * Deletes the field when nothing qualifies: an absent mirror reads as \"no\n * update to offer\", while a stale string reads as an update that does not\n * exist.\n */\nasync function repairLatestApprovedVersion(\n listingRef: FirebaseFirestore.DocumentReference,\n revocation: PluginRevocation | null | undefined,\n): Promise<void> {\n const versions = await listingRef\n .collection('pluginVersions')\n .orderBy('publishedAt', 'desc')\n .limit(50)\n .get()\n // The DECISION lives in core (`newestInstallableVersion`), where it is\n // testable without a Firestore double and shared with anything else that\n // has to answer \"what is on offer\". This function is only the query.\n const newest = newestInstallableVersion(\n versions.docs.map((doc) => ({\n version: doc.id,\n reviewState: doc.get('reviewState'),\n })),\n revocation,\n compareArtifactVersions,\n )\n await updateExisting(listingRef, {\n latestApprovedVersion: newest ?? FieldValue.delete(),\n updatedAt: FieldValue.serverTimestamp(),\n })\n}\n\n/** Rows a queue section reads before it says there are more. */\nconst REVIEW_QUEUE_PAGE = 100\n/** The most a reviewer can page the queue out to. */\nconst REVIEW_QUEUE_MAX = 1000\n\nconst queryParam = (value: unknown): string =>\n String(Array.isArray(value) ? (value[0] ?? '') : (value ?? ''))\n\n/**\n * The staff review index (AGL-961), every section on its query (AGL-3321).\n *\n * Three sections, each its own query over live plugin listings:\n *\n * - Awaiting review: the newest bytes have no approval. Read from the\n * listing's `latestVersionReviewState` summary, whose `pending` and\n * `rejected` are exactly \"the version's own `reviewState` is not\n * `approved`\" — `revoked` is the one summary value a version keeps its\n * `approved` under, and it is not in `AWAITING_REVIEW_STATES`, so a killed\n * version never re-enters the queue looking unread (AGL-1121).\n * - Listed: `reviewStatus` listed or verified.\n * - Verification requested: the publisher's standing ask (AGL-1217).\n *\n * The Status select and the search (`?status=`, `?q=`) are clauses on every\n * section's query, planned once by `REVIEW_QUEUE_QUERY`; search reads the\n * listing name's `nameTokens`. It used to be matched over one window of a\n * hundred plugin listings, so a plugin past it was in no section at all.\n * `?limit=` pages each section out; a section that holds more than it read\n * says so rather than presenting a short list as the whole queue.\n */\nasync function reviewQueue(\n firestore: FirebaseFirestore.Firestore,\n query: Record<string, unknown>,\n): Promise<Response> {\n const clauses = reviewQueueStatusClauses(queryParam(query['status']))\n const words = queryParam(query['q']).split(/\\s+/).filter(Boolean)\n const asked = Math.floor(Number(queryParam(query['limit'])))\n const pageLimit = Number.isFinite(asked) && asked > 0\n ? Math.min(asked, REVIEW_QUEUE_MAX)\n : REVIEW_QUEUE_PAGE\n const listings = firestore.collection('marketplaceListings')\n\n let refused: ListQueryPlan['refused'] = []\n let notices: string[] = []\n const more: Record<ReviewQueueSection, boolean> = {\n queue: false,\n listed: false,\n verification: false,\n }\n const read = async (section: ReviewQueueSection) => {\n const base = reviewQueueBase(section, clauses)\n // A Status the section cannot hold: empty by definition, never queried.\n if (!base) return []\n const plan = planListQuery(\n REVIEW_QUEUE_QUERY,\n { clauses, search: words, base },\n nameSearchNormalizers,\n )\n refused = plan.refused\n notices = plan.notices\n const snapshot = await applyListQuery(listings, plan)\n .limit(pageLimit + 1)\n .get()\n more[section] = snapshot.docs.length > pageLimit\n return snapshot.docs.slice(0, pageLimit)\n }\n const [queueDocs, listedDocs, verificationDocs] = await Promise.all([\n read('queue'),\n read('listed'),\n read('verification'),\n ])\n\n // Rows only (AGL-961). This used to DOWNLOAD every queued bundle to re-run\n // the verifier, so the index paid a Storage round trip per submission\n // before it could paint. The verifier now runs on the detail page, for the\n // one listing being read.\n const reviewRow = async (doc: FirebaseFirestore.QueryDocumentSnapshot) => {\n const listing = doc.data()\n const version = String(listing.latestVersion ?? '')\n const latest = version\n ? await doc.ref.collection('pluginVersions').doc(version).get()\n : null\n return {\n listingId: doc.id,\n displayName: listing.displayName ?? doc.id,\n description: listing.description ?? '',\n license: listing.license ?? '',\n categories: listing.categories ?? [],\n profileId: listing.profileId,\n reviewStatus: listing.reviewStatus ?? 'submitted',\n priceUsd: Number(listing.priceUsd ?? 0),\n version,\n hidden: Boolean(listing.hiddenAt),\n private: listing.visibility === 'private',\n latestReviewState: String(latest?.get('reviewState') ?? 'pending'),\n grandfathered: Boolean(latest?.get('grandfathered')),\n // The publisher's standing ask for the badge (AGL-1217).\n verificationRequest: listing.verificationRequest ?? null,\n }\n }\n const queue = await Promise.all(queueDocs.map(reviewRow))\n // A THIRD section, deliberately not folded into `queue` (AGL-1217).\n // `queue` means \"these bytes have not been read\"; a verification request\n // means \"this publisher asked us to vouch for who they are\". A listing can\n // sit in both at once, and merging them would hide one behind the other.\n const verificationRequests = await Promise.all(verificationDocs.map(reviewRow))\n // Listed/verified plugins with per-version trust (AGL-885): once a listing\n // leaves the queue the Grant/Revoke realm-trust actions used to leave with\n // it. This keeps every listed plugin's version trust state administrable.\n const listed = await Promise.all(\n listedDocs.map(async (doc) => {\n const listing = doc.data()\n const versionsSnapshot = await doc.ref\n .collection('pluginVersions')\n .orderBy('publishedAt', 'desc')\n .limit(10)\n .get()\n const versions = versionsSnapshot.docs.map((versionDoc) => ({\n version: String(versionDoc.get('version') ?? versionDoc.id),\n trust: versionDoc.get('trust') ?? null,\n reviewState: String(versionDoc.get('reviewState') ?? 'pending'),\n }))\n return {\n listingId: doc.id,\n displayName: listing.displayName ?? doc.id,\n reviewStatus: listing.reviewStatus,\n profileId: listing.profileId,\n latestVersion: String(listing.latestVersion ?? ''),\n // Takedown state (AGL-952), so a row shows the current verdict rather\n // than sending a reviewer into the detail page to find out whether\n // the plugin is stopped.\n hidden: Boolean(listing.hiddenAt),\n hiddenReason: String(listing.hiddenReason ?? ''),\n private: listing.visibility === 'private',\n pendingVersions: versions.filter((entry) => entry.reviewState !== 'approved')\n .length,\n // Summarised for the row; the per-version controls live on the detail\n // page (AGL-960).\n realmVersions: versions.filter((entry) => entry.trust === 'realm').length,\n versionCount: versions.length,\n versions,\n }\n }),\n )\n\n // Publisher names for scanning (AGL-961) — a listing id tells a reviewer\n // nothing. One batched read for every section.\n const publisherIds = [\n ...new Set(\n [...queue, ...listed, ...verificationRequests]\n .map((entry) => String(entry.profileId ?? ''))\n .filter(Boolean),\n ),\n ]\n const publishers: Record<string, string> = {}\n if (publisherIds.length) {\n const docs = await firestore.getAll(\n ...publisherIds.map((id) => firestore.collection('orgs').doc(id)),\n )\n for (const doc of docs) {\n if (doc.exists) publishers[doc.id] = String(doc.get('name') ?? doc.id)\n }\n }\n return Response.json(\n {\n queue,\n listed,\n publishers,\n verificationRequests,\n refused,\n notices,\n more,\n limit: pageLimit,\n },\n { status: 200 },\n )\n}\n\nasync function handler(request: Request): Promise<Response> {\n const { method, body, query, headers: rawHeaders } =\n await pluginRequestFromWeb(request)\n const headers = rawHeaders as Partial<Record<string, string>>\n const authorization = headers.authorization ?? ''\n const idToken = authorization.startsWith('Bearer ')\n ? authorization.slice('Bearer '.length)\n : undefined\n if (!idToken) return Response.json({ error: 'Unauthenticated' }, { status: 401 })\n\n try {\n const decoded = await firebaseAdmin.app().auth().verifyIdToken(idToken)\n if (!decoded.email_verified && !isImpersonationSession(decoded)) {\n return emailUnverifiedResponse()\n }\n if (!decoded['staff']) {\n return Response.json({ error: 'Staff only' }, { status: 403 })\n }\n const firestore = firebaseAdmin.app().firestore()\n\n if (method === 'GET') {\n const detailId = String(query['listingId'] ?? '')\n if (detailId) {\n return listingDetail(firestore, detailId, String(query['version'] ?? ''))\n }\n\n return reviewQueue(firestore, query)\n }\n\n if (method !== 'POST') {\n return Response.json({ error: 'Method not allowed' }, { status: 405 })\n }\n const listingId = String(body?.listingId ?? '')\n const action = String(body?.action ?? '')\n\n // Takedown (AGL-658) is separate from the review verdict: it applies to\n // EVERY artifact type, not just plugins, and it must not overwrite a\n // plugin's `reviewStatus` — a hidden plugin that later gets un-hidden\n // should return to the verdict it had, not to square one.\n if (action === 'hide' || action === 'unhide') {\n if (!listingId) {\n return Response.json({ error: 'Missing listingId' }, { status: 400 })\n }\n const hideReason = String(body?.reason ?? '').slice(0, 500)\n if (action === 'hide' && !hideReason.trim()) {\n return Response.json({ error: 'Hiding needs a reason' }, { status: 400 })\n }\n const reviewUid = String(body?.reviewUid ?? '')\n const target = reviewUid\n ? firestore\n .collection('marketplaceListings')\n .doc(listingId)\n .collection('reviews')\n .doc(reviewUid)\n : firestore.collection('marketplaceListings').doc(listingId)\n const targetSnapshot = await target.get()\n if (!targetSnapshot.exists) {\n return Response.json({ error: 'Unknown target' }, { status: 404 })\n }\n // A takedown strips the Verified badge (AGL-1121, decided 2026-08-03).\n //\n // Verified is OUR claim that a human vouched for this publisher. Taking\n // the listing down is us saying the opposite out loud, so the two cannot\n // both stand — a badge surviving a takedown would still be asserting the\n // vouch on the listing page the moment it was restored.\n //\n // Demoted to `listed`, not to `rejected` or `submitted`: the takedown\n // itself is what makes it non-browsable (`hiddenAt`), and rewriting the\n // review verdict would destroy the record of a review that did happen.\n //\n // Restoring deliberately does NOT put the badge back. Re-granting is\n // `verify`, which re-checks the review checklist server-side; an automatic\n // regrant would hand back the badge without anyone re-forming the opinion\n // behind it. Losing it to a takedown is meant to cost a re-review.\n const stripVerified = shouldStripVerifiedOnTakedown({\n action,\n reviewStatus: targetSnapshot.get('reviewStatus'),\n isListingTarget: !reviewUid,\n })\n await target.set(\n reviewUid\n ? { hidden: action === 'hide' }\n : action === 'hide'\n ? {\n hiddenAt: FieldValue.serverTimestamp(),\n hiddenBy: decoded.uid,\n hiddenReason: hideReason,\n ...(stripVerified\n ? { reviewStatus: VERIFIED_STRIPPED_STATUS }\n : {}),\n }\n : {\n hiddenAt: FieldValue.delete(),\n hiddenBy: FieldValue.delete(),\n hiddenReason: FieldValue.delete(),\n },\n { merge: true },\n )\n // A takedown leaves browse for everyone but its publisher, and the\n // queue's Taken down status reads it (AGL-3321).\n if (!reviewUid) await refreshListingQueryFields(target)\n\n // Takedown means takedown (AGL-948). Hiding a PLUGIN listing also\n // writes the kill switch, so one staff action has one outcome\n // instead of leaving the bundle executing in every workspace that\n // already installed it. The realm join blocks on `hiddenAt` too, but\n // the revocation is what the client-side loaders and the public\n // listing-versions endpoint already understand — belt and braces on\n // the one action where a gap means running attacker code.\n const isPlugin =\n !reviewUid &&\n (targetSnapshot.get('artifactType') === 'plugin' ||\n targetSnapshot.get('type') === 'plugin')\n /**\n * An email starter earns the same treatment for the same reason.\n *\n * It is copied on install, so `hiddenAt` alone reaches only the\n * storefront: every tenant who already installed it goes on MAILING it,\n * from the sending domain every other tenant shares. The revocation is\n * what `emailStarterSendBlock` reads at the send, which is the only\n * chokepoint that can still refuse.\n *\n * The five other copied types are deliberately not here. Their content\n * is rendered on the tenant's own site, where `hiddenAt` blocking the\n * next install is the whole of what a takedown can honestly promise —\n * stopping a page from rendering is a different decision, and one nobody\n * has made.\n */\n const killsInstalledCopies =\n isPlugin ||\n (!reviewUid && targetSnapshot.get('artifactType') === 'emailStarter')\n if (killsInstalledCopies) {\n const revocationRef = firestore.collection('revocations').doc(listingId)\n const current = (await revocationRef.get()).data() as\n | PluginRevocation\n | undefined\n // Both transitions go through the shared helper (AGL-1085) so a\n // takedown and a per-version review revocation can coexist. Restoring\n // used to DELETE the doc whenever it was takedown-owned, which also\n // un-revoked any version a reviewer had stopped for an unrelated\n // reason — `reviewVersions` is what survives the round trip.\n const next = nextRevocationState(current, {\n type: action === 'hide' ? 'takedown' : 'restore',\n })\n if (next) {\n await revocationRef.set(\n {\n ...next,\n ...(action === 'hide' ? { reason: hideReason } : {}),\n revokedBy: decoded.uid,\n revokedAt: FieldValue.serverTimestamp(),\n // A restore drops takedown ownership; the field has to go, not\n // merely be overwritten, or the next restore re-deletes.\n ...(action === 'hide' ? {} : { source: FieldValue.delete() }),\n },\n { merge: true },\n )\n } else if (current) {\n await revocationRef.delete()\n }\n // Make the kill switch reach ALREADY-CACHED pages (AGL-1152). The\n // tenant stamps each plugin node with its revocation state at compose\n // time, so without this the bundle we just killed keeps executing on\n // every cached page until it happens to re-render. Best effort: the\n // tenant refuses a revoked plugin at render time regardless.\n //\n // Plugin-only: it walks the plugin INSTALL PINS, which an email\n // starter has none of, and an email is never part of a cached page —\n // its kill is felt at the send, where nothing is cached.\n if (isPlugin) await dropCachesForListing(firestore, listingId)\n // The offer follows the kill switch here too (AGL-2368). AGL-2306\n // taught the per-version revoke and the reject path to repair the\n // mirror and left this one out, so a takedown flattened `versions` to\n // `'all'` — revoking every build — while `latestApprovedVersion` went\n // on naming one. `hiddenAt` hides the listing from browse and blocks\n // the install route, so nothing was installable through it; but a\n // restore clears `hiddenAt` first and the mirror is what the update\n // badges read, and `nextRevocationState` can return a document that\n // still holds a reviewer's per-version revocations. Recomputed from\n // the versions in both directions rather than reasoned about.\n //\n // Named explicitly rather than reusing `target`: `isPlugin` is only\n // true when `reviewUid` is empty, so they are the same document — but\n // that is a fact two conditions apart, and a repair pointed at a\n // review subdocument would write a `latestApprovedVersion` onto it.\n //\n // Plugin-only, unlike the revocation write above: the mirror is\n // recomputed from `pluginVersions`, a collection no other artifact\n // type has, so running it for an email starter would derive \"nothing\n // approved\" from an empty read and write that over the listing.\n if (isPlugin) {\n await repairLatestApprovedVersion(\n firestore.collection('marketplaceListings').doc(listingId),\n next,\n )\n }\n }\n\n await addAdminAudit(firestore, {\n actorUid: decoded.uid,\n action: `plugins.takedown.${action}`,\n target: reviewUid\n ? `marketplaceListings/${listingId}/reviews/${reviewUid}`\n : `marketplaceListings/${listingId}`,\n /*\n * A review document is keyed by its AUTHOR's uid, so hiding one is a\n * staff act against a named person. The target names the review, as\n * it must — but on its own that put the takedown nowhere near the\n * page of the person whose words were removed.\n */\n ...(reviewUid ? { subjectUid: reviewUid } : {}),\n after: {\n hidden: action === 'hide',\n ...(hideReason ? { reason: hideReason } : {}),\n ...(killsInstalledCopies ? { revoked: action === 'hide' } : {}),\n // Recorded because it is a side effect of the takedown rather than\n // something the reviewer asked for, and because getting it back is a\n // re-review rather than an undo.\n ...(stripVerified ? { unverified: true } : {}),\n },\n at: FieldValue.serverTimestamp(),\n })\n\n return Response.json(\n {\n ok: true,\n hidden: action === 'hide',\n revoked: killsInstalledCopies && action === 'hide',\n // The caller shows this — a badge silently disappearing would be\n // worse than one that never existed.\n unverified: stripVerified,\n },\n { status: 200 },\n )\n }\n\n // Review checklist (AGL-963). Ticks are per {version, sha256} and carry\n // who + when, so \"verified\" is a recorded act rather than a click.\n if (action === 'checklist') {\n const version = String(body?.version ?? '')\n const itemId = String(body?.itemId ?? '')\n const checked = body?.checked !== false\n if (!listingId || !version || !REQUIRED_OR_OPTIONAL.has(itemId)) {\n return Response.json({ error: 'Unknown checklist item' }, { status: 400 })\n }\n const versionRef = firestore\n .collection('marketplaceListings')\n .doc(listingId)\n .collection('pluginVersions')\n .doc(version)\n const versionSnapshot = await versionRef.get()\n if (!versionSnapshot.exists) {\n return Response.json({ error: 'Unknown version' }, { status: 404 })\n }\n await versionRef.set(\n {\n reviewChecklist: {\n [itemId]: checked\n ? {\n by: decoded.uid,\n at: FieldValue.serverTimestamp(),\n // Pins the tick to the bytes it was made against.\n sha256: String(versionSnapshot.get('sha256') ?? ''),\n }\n : FieldValue.delete(),\n },\n },\n { merge: true },\n )\n // Audited (AGL-971): a checklist tick is the record that a human\n // looked, so it needs the same trail as the verdict it unlocks —\n // including WHICH bytes were looked at.\n await addAdminAudit(firestore, {\n actorUid: decoded.uid,\n action: `plugins.review.checklist.${checked ? 'check' : 'uncheck'}`,\n target: `marketplaceListings/${listingId}/pluginVersions/${version}`,\n after: {\n itemId,\n checked,\n sha256: String(versionSnapshot.get('sha256') ?? ''),\n },\n at: FieldValue.serverTimestamp(),\n })\n return Response.json({ ok: true, itemId, checked }, { status: 200 })\n }\n\n // Per-version verdicts (AGL-966). Approval is a statement about bytes,\n // so it lives on the version doc and installs resolve the newest\n // approved one. Listing-level list/verify still exist, but they can no\n // longer ship code past review on their own.\n if (action === 'approve-version' || action === 'reject-version') {\n const version = String(body?.version ?? '')\n const listingRef = firestore.collection('marketplaceListings').doc(listingId)\n const versionRef = listingRef.collection('pluginVersions').doc(version)\n const versionSnapshot = await versionRef.get()\n if (!versionSnapshot.exists) {\n return Response.json({ error: 'Unknown version' }, { status: 404 })\n }\n // The LISTING has to exist too, and the check belongs up here rather\n // than beside the writes that need it (AGL-1766). A version outliving\n // its listing is not hypothetical — Firestore deletes are not\n // recursive, so `pluginVersions` survives whatever removed the parent.\n //\n // The read below used to be `(await listingRef.get()).data() ?? {}`,\n // and that default was not a convenience: it is what made the two\n // mirrors fire. Both of their conditions are TRUE on `{}` —\n // `!['listed','verified'].includes('')` and `previous == null` — so an\n // absent listing was resurrected as `{ reviewStatus: 'listed' }`, i.e.\n // browsable in the marketplace, from a merge-set. (The third mirror,\n // `latestVersionReviewState`, compares `String(latestVersion ?? '')`\n // against a non-empty `version` and is false on `{}` — it could not\n // fire. The pattern is not uniform even inside one block, which is\n // exactly why AGL-1763 could not express this as a lint rule.)\n //\n // Read BEFORE the verdict write, not after it. Refusing must not\n // discard work that already happened (AGL-1760); refusing here happens\n // before anything has, so the reviewer simply retries against a\n // listing that exists. `?? {}` is gone with it — kept, it would have\n // traded a resurrection for an `update()` rejection served as a 500.\n const listingSnapshot = await listingRef.get()\n if (!listingSnapshot.exists) {\n return Response.json({ error: 'Unknown listing' }, { status: 404 })\n }\n const listing = listingSnapshot.data()\n const sha256 = String(versionSnapshot.get('sha256') ?? '')\n const approving = action === 'approve-version'\n if (approving) {\n const outstanding = outstandingChecklistItems(\n versionSnapshot.get('reviewChecklist'),\n sha256,\n )\n if (outstanding.length) {\n return Response.json(\n {\n error: `Review checklist incomplete — ${outstanding.length} required item(s) outstanding for these bytes`,\n outstanding,\n },\n { status: 409 },\n )\n }\n }\n const reason = String(body?.reason ?? '').slice(0, 500)\n // Structured rejection (AGL-977). The category is what makes rejections\n // comparable across reviewers and queryable afterwards; the comment is\n // what makes one actionable. Requiring only free text gave neither.\n const category = String(body?.category ?? '')\n if (!approving) {\n const invalid = rejectionInputError(category, reason)\n if (invalid) return Response.json({ error: invalid }, { status: 400 })\n }\n await versionRef.set(\n {\n reviewState: approving ? 'approved' : 'rejected',\n reviewedBy: decoded.uid,\n reviewedAt: FieldValue.serverTimestamp(),\n // Records WHICH bytes were approved, so a later republish under\n // the same version string can never inherit this verdict.\n reviewedSha256: sha256,\n grandfathered: FieldValue.delete(),\n ...(approving\n ? {\n // Clear a previous rejection's fields on approval, or a\n // version that was rejected and then approved keeps\n // explaining why it was turned down.\n reviewRejectionReason: FieldValue.delete(),\n reviewRejectionCategory: FieldValue.delete(),\n }\n : {\n reviewRejectionReason: reason,\n reviewRejectionCategory: category,\n // REALM TRUST IS WITHDRAWN WITH THE APPROVAL (AGL-2306).\n //\n // `admin-trust` refuses to grant `trust: 'realm'` unless the\n // version is approved — approval gates the grant. Nothing\n // ungated it: the realm load path checks `hiddenAt`, the sha,\n // the signature and the revocation, and never re-reads\n // `reviewState`. So approve → sign → re-review → reject left\n // the version loading IN THE APP REALM, where neither the\n // sandbox iframe nor the plugin-origin CSP is between it and\n // user data, until staff separately reached for the kill\n // switch.\n //\n // The same four fields `admin-trust`'s own revoke branch\n // clears, so there is one shape of \"untrusted\" rather than\n // two. This does NOT stop the bundle running as a sandboxed\n // plugin — that is what the per-version revocation beside\n // this decision is for, and it is deliberately a separate\n // choice (a thin README is the usual rejection, and an\n // unannounced site outage is worse). It withdraws only the\n // privilege that approval was the precondition for.\n trust: FieldValue.delete(),\n signature: FieldValue.delete(),\n trustGrantedBy: FieldValue.delete(),\n trustGrantedAt: FieldValue.delete(),\n }),\n },\n { merge: true },\n )\n\n // A plugin with its first approved version becomes browsable. Later\n // approvals never change listing status — that is the point: an\n // update is reviewed without disturbing what customers already have.\n //\n // The three mirrors below write through `updateExisting` as the second\n // line for the window the check above cannot close — a listing deleted\n // mid-handler. Every payload here is FLAT with no delete sentinel, so\n // the switch is semantically identical to the merge-set it replaces;\n // the `false` return needs no branch, because a listing that is gone by\n // now wants nothing mirrored onto it.\n\n // Mirror this verdict onto the listing for the marketplace (AGL-1121),\n // but ONLY when it is the newest version. Approving an old version\n // must not let the listing claim its newest bytes were reviewed —\n // which is the exact shape of the bug this mirror exists to fix.\n if (String(listing.latestVersion ?? '') === version) {\n await updateExisting(listingRef, {\n latestVersionReviewState: approving ? 'approved' : 'rejected',\n })\n }\n const listsNow =\n approving &&\n !['listed', 'verified'].includes(String(listing.reviewStatus ?? ''))\n if (listsNow) {\n await updateExisting(listingRef, {\n reviewStatus: 'listed',\n updatedAt: FieldValue.serverTimestamp(),\n })\n // Listed is browsable: the browse audience follows (AGL-3321).\n await refreshListingQueryFields(listingRef)\n }\n\n // Denormalise the newest approved version onto the listing (AGL-1016).\n // `pluginVersions` is server-only, so a console showing \"update\n // available\" has nothing else to read — and reading `latestVersion`\n // instead would advertise a version the install route refuses, leaking\n // AGL-966's guarantee back out through a badge.\n //\n // Only ever moves forward: approving an older version after a newer one\n // is a real sequence (a reviewer working through a backlog) and must not\n // walk the offer backwards.\n // What new installs receive once this lands, for the publisher's copy.\n let offeredVersion = String(listing.latestApprovedVersion ?? '')\n if (approving) {\n const previous = listing.latestApprovedVersion\n if (\n previous == null ||\n (compareArtifactVersions(String(previous), version) ?? 0) < 0\n ) {\n await updateExisting(listingRef, {\n latestApprovedVersion: version,\n updatedAt: FieldValue.serverTimestamp(),\n })\n offeredVersion = version\n }\n } else if (String(listing.latestApprovedVersion ?? '') === version) {\n // …and BACK when the version being offered is the one just rejected\n // (AGL-2306). Nothing did this, so a re-review that turned a live\n // version down left the listing advertising it — an \"Update to vX\"\n // for bytes `install-plugin` answers 409 to.\n const revocation = (\n await firestore.collection('revocations').doc(listingId).get()\n ).data() as PluginRevocation | undefined\n await repairLatestApprovedVersion(listingRef, revocation)\n }\n\n await addAdminAudit(firestore, {\n actorUid: decoded.uid,\n action: `plugins.review.version.${approving ? 'approve' : 'reject'}`,\n target: `marketplaceListings/${listingId}/pluginVersions/${version}`,\n after: {\n sha256,\n ...(reason ? { reason } : {}),\n // Both, not one (AGL-971 + AGL-977): the category is what an audit\n // can be counted by, the comment is what makes a single row make\n // sense to a human reading it later.\n ...(category ? { category } : {}),\n },\n at: FieldValue.serverTimestamp(),\n })\n\n // Pins sitting on these exact bytes right now (AGL-1085). Rejecting a\n // version does NOT stop it — the runtime resolves a pin by\n // {version, sha256} and only asks whether it is revoked — so both\n // sides have to be told, and the reviewer needs the number before\n // deciding whether to reach for the kill switch.\n const liveInstalls = Number(versionSnapshot.get('activeInstalls') ?? 0)\n const stranded = !approving && liveInstalls > 0\n\n if (listing.profileId) {\n const verdict = versionVerdictBody({\n approving,\n name: String(listing.displayName ?? ''),\n version,\n offeredVersion,\n listedNow: listsNow && !isPrivateListing(listing),\n category,\n reason,\n liveInstalls,\n })\n await notifyOrgAdmins(String(listing.profileId), {\n type: 'marketplace.review',\n level: approving ? 'success' : 'warning',\n title: approving\n ? `\"${listing.displayName}\" v${version} approved`\n : `\"${listing.displayName}\" v${version} was not approved`,\n body: verdict,\n orgId: String(listing.profileId),\n link: '/',\n }).catch(() => undefined)\n await emailPublisher(\n String(listing.profileId),\n approving\n ? `${listing.displayName} v${version} passed review`\n : `${listing.displayName} v${version} was not approved`,\n verdict,\n {\n frame: {\n plugin: String(listing.displayName ?? ''),\n version,\n outcome: approving ? 'Approved' : 'Not approved',\n },\n },\n )\n }\n\n return Response.json(\n {\n ok: true,\n version,\n reviewState: approving ? 'approved' : 'rejected',\n // Lets the reviewer's confirmation say what it actually did, and\n // offer the kill switch when the bytes are live somewhere.\n liveInstalls,\n stranded,\n },\n { status: 200 },\n )\n }\n\n // Per-version kill switch (AGL-1085). Until now a reviewer's only way to\n // stop live bytes was a listing-wide takedown, which also revokes the\n // approved version customers are happily running and hides the listing.\n // Rejection deliberately stays a verdict rather than a kill: most\n // rejections are a thin README, and an unannounced site outage is worse\n // than the gap. This is the deliberate, adjacent action.\n //\n // This does NOT strip the Verified badge, unlike a takedown (AGL-1121).\n // The two claims are scoped differently and the split is the whole point:\n // Verified says a human vouched for the PUBLISHER and survives version\n // bumps, while the separate \"Reviewed\" chip speaks for THESE bytes and is\n // re-earned per version. Stripping the publisher claim for one bad release\n // would punish an honest mistake, and is not reversible without a full\n // re-review. A takedown is the action that contradicts the publisher claim,\n // and that one does strip it.\n //\n // That reasoning only holds because the BYTES claim is withdrawn instead —\n // which it now is, below. It was not before, and the gap is what made\n // keeping the badge unsafe rather than merely debatable.\n if (action === 'revoke-version' || action === 'unrevoke-version') {\n const version = String(body?.version ?? '')\n if (!listingId || !version) {\n return Response.json(\n { error: 'Listing and version required' },\n { status: 400 },\n )\n }\n const listingRef = firestore.collection('marketplaceListings').doc(listingId)\n const listing = (await listingRef.get()).data() ?? {}\n const revocationRef = firestore.collection('revocations').doc(listingId)\n const current = (await revocationRef.get()).data() as\n | PluginRevocation\n | undefined\n const revoking = action === 'revoke-version'\n const next = nextRevocationState(current, {\n type: revoking ? 'revoke-version' : 'unrevoke-version',\n version,\n })\n if (next) {\n await revocationRef.set(\n {\n ...next,\n reason: String(body?.reason ?? current?.reason ?? '').slice(0, 500),\n revokedBy: decoded.uid,\n revokedAt: FieldValue.serverTimestamp(),\n },\n { merge: true },\n )\n } else {\n await revocationRef.delete()\n }\n // Same reach as the takedown path above (AGL-1152): a per-version\n // revocation changes what every cached page renders, and nothing else\n // drops that HTML.\n await dropCachesForListing(firestore, listingId)\n\n // Withdraw the \"Reviewed\" chip when the bytes we just killed are the ones\n // customers are being offered (AGL-1121).\n //\n // This was ASSUMED to happen already and did not. `latestVersionReviewState`\n // is written only by approve/reject and on publish, so a version approved\n // and later revoked kept `'approved'` — and since a per-version revocation\n // deliberately does NOT hide the listing (that is the whole difference from\n // a takedown), the marketplace went on showing \"A human at Aglyn read these\n // exact bytes\" about bytes we had just stopped from executing. Revocation\n // is not surfaced anywhere else in the browse or listing UI either, so\n // nothing contradicted it.\n //\n // `revoked` rather than `rejected`: it was not turned down in review, it\n // was killed afterwards, and the audit trail should not blur those. Both\n // consumers test against `'approved'`, so this correctly drops the chip and\n // raises the caution alert.\n //\n // Only when it is the LATEST version, because that is what both consumers\n // describe. Revoking an old version says nothing about what is on offer.\n const isLatest = revocationWithdrawsReviewedClaim({\n revokedVersion: version,\n latestVersion: String(listing['latestVersion'] ?? ''),\n })\n if (isLatest) {\n const versionSnapshot = await listingRef\n .collection('pluginVersions')\n .doc(version)\n .get()\n await listingRef.set(\n {\n latestVersionReviewState: revoking\n ? REVOKED_VERSION_REVIEW_STATE\n : // Restoring returns it to whatever the version's own verdict\n // says, rather than assuming `approved` — un-revoking a version\n // that was never approved must not promote it.\n String(versionSnapshot.get('reviewState') ?? 'pending'),\n },\n { merge: true },\n )\n }\n\n // The offer follows the kill switch (AGL-2306). A revoked version is\n // refused by `install-plugin`, so leaving it as `latestApprovedVersion`\n // advertises an update that cannot be taken; un-revoking restores it.\n // Both directions, because both change what is installable.\n await repairLatestApprovedVersion(listingRef, next)\n\n await addAdminAudit(firestore, {\n actorUid: decoded.uid,\n action: `plugins.revocation.${revoking ? 'revoke' : 'restore'}`,\n target: `marketplaceListings/${listingId}/pluginVersions/${version}`,\n after: {\n versions: next?.versions ?? null,\n ...(isLatest ? { latestVersionReviewStateChanged: true } : {}),\n },\n at: FieldValue.serverTimestamp(),\n })\n\n if (listing.profileId) {\n await notifyOrgAdmins(String(listing.profileId), {\n type: 'marketplace.review',\n // Stopped on every site that runs it, which is an outage for them.\n level: revoking ? 'critical' : 'success',\n title: revoking\n ? `\"${listing.displayName}\" v${version} was stopped`\n : `\"${listing.displayName}\" v${version} was allowed to run again`,\n body: revoking\n ? `${pluginAndVersion(String(listing.displayName ?? ''), version)} ` +\n 'has been stopped on every site running it. Those sites now ' +\n 'show a placeholder where the plugin was.'\n : `${pluginAndVersion(String(listing.displayName ?? ''), version)} ` +\n 'is allowed to run again, and sites running it are no longer ' +\n 'blocked.',\n orgId: String(listing.profileId),\n link: '/',\n }).catch(() => undefined)\n }\n\n return Response.json(\n { ok: true, version, revoked: revoking },\n { status: 200 },\n )\n }\n\n // Declining a verification request (AGL-1217). Handled before the ACTIONS\n // lookup because it deliberately has NO `reviewStatus` to move to: the\n // listing stays exactly as live as it was. Refusing a badge is not a\n // verdict on the code, and routing it through the status ladder would\n // make it one.\n if (action === 'decline-verification') {\n const declineReason = String(body?.reason ?? '').trim().slice(0, 500)\n if (!listingId) {\n return Response.json({ error: 'Unknown action' }, { status: 400 })\n }\n // Required, unlike most fields here. The publisher is notified of this\n // and then has to wait out a cooldown before asking again; \"no, and we\n // will not say why, try in a month\" is not a usable answer.\n if (!declineReason) {\n return Response.json(\n { error: 'A reason is required — the publisher is told it' },\n { status: 400 },\n )\n }\n const listingRef = firestore\n .collection('marketplaceListings')\n .doc(listingId)\n const listing = (await listingRef.get()).data()\n if (!listing) {\n return Response.json({ error: 'Unknown listing' }, { status: 404 })\n }\n if (listing.verificationRequest?.state !== 'pending') {\n return Response.json(\n { error: 'No verification request is waiting' },\n { status: 409 },\n )\n }\n await listingRef.set(\n {\n verificationRequest: {\n ...listing.verificationRequest,\n state: 'declined',\n decidedAt: FieldValue.serverTimestamp(),\n decidedBy: decoded.uid,\n declineReason,\n },\n },\n { merge: true },\n )\n /*\n * THE AUDIT ROW THIS BRANCH NEVER WROTE (AGL-2328).\n *\n * Every sibling branch in this file audits, and the file header at the\n * top claims the route is audited. This one mutated\n * `verificationRequest.state`, notified the publisher and started a\n * cooldown, and left no record — so a decline was the one staff\n * decision here that could not be reviewed afterwards, on the action\n * whose reason staff are REQUIRED to type.\n *\n * `reason` uses the audit log's own reason column rather than being\n * buried in `after`, because the audit page renders and exports that\n * column and searches it (AGL-1652) — a why nobody can filter on is a\n * why nobody reads.\n */\n await addAdminAudit(firestore, {\n actorUid: decoded.uid,\n actorEmail: decoded.email ? String(decoded.email) : null,\n action: 'plugins.verification.decline',\n scope: 'marketplace',\n target: `marketplaceListings/${listingId}`,\n before: { verificationState: 'pending' },\n after: {\n verificationState: 'declined',\n cooldownDays: VERIFICATION_DECLINE_COOLDOWN_DAYS,\n },\n reason: declineReason,\n at: FieldValue.serverTimestamp(),\n })\n\n const publisherOrgId = String(listing.profileId ?? '')\n if (publisherOrgId) {\n await notifyOrgAdmins(publisherOrgId, {\n type: 'marketplace.review',\n level: 'warning',\n title: `Verification declined for \"${listing.displayName}\"`,\n // Says plainly that nothing about the listing changed. Without it a\n // publisher reads \"declined\" as a takedown of the plugin itself.\n body:\n `We declined the verified badge for ${listing.displayName}. The ` +\n 'plugin itself is unaffected and stays listed.\\n\\n' +\n `Reason: ${declineReason}\\n\\n` +\n 'You can request verification again in ' +\n `${VERIFICATION_DECLINE_COOLDOWN_DAYS} days.`,\n orgId: publisherOrgId,\n link: '/',\n }).catch(() => undefined)\n }\n return Response.json({ ok: true, state: 'declined' }, { status: 200 })\n }\n\n const nextStatus = ACTIONS[action]\n if (!listingId || !nextStatus) {\n return Response.json({ error: 'Unknown action' }, { status: 400 })\n }\n const reason = String(body?.reason ?? '').slice(0, 500)\n const category = String(body?.category ?? '')\n if (action === 'reject') {\n const invalid = rejectionInputError(category, reason)\n if (invalid) return Response.json({ error: invalid }, { status: 400 })\n }\n\n const listingRef = firestore.collection('marketplaceListings').doc(listingId)\n const listing = (await listingRef.get()).data()\n if (!listing) return Response.json({ error: 'Unknown listing' }, { status: 404 })\n\n // Both gates that expose a plugin to customers require a completed\n // checklist (AGL-963).\n //\n // `list` matters MORE than `verify`, which is easy to get backwards:\n // listing is what makes `isListingBrowsable` true, so it is the moment\n // executable third-party code becomes installable by every workspace.\n // `verify` only adds the badge on top. Gating the badge while leaving\n // listing open would put the ceremony on the weaker action.\n //\n // `start-review` and `reject` stay ungated on purpose: a reviewer must\n // be able to throw something out without first ticking eight boxes\n // about a bundle they have already decided against.\n if (action === 'verify' || action === 'list') {\n const version = String(listing.latestVersion ?? '')\n const versionSnapshot = await listingRef\n .collection('pluginVersions')\n .doc(version)\n .get()\n const outstanding = outstandingChecklistItems(\n versionSnapshot.get('reviewChecklist'),\n String(versionSnapshot.get('sha256') ?? ''),\n )\n if (outstanding.length) {\n return Response.json(\n {\n error: `Review checklist incomplete — ${outstanding.length} required item(s) outstanding`,\n outstanding,\n },\n { status: 409 },\n )\n }\n }\n\n await listingRef.set(\n {\n reviewStatus: nextStatus,\n reviewedBy: decoded.uid,\n reviewedAt: FieldValue.serverTimestamp(),\n // Granting the badge answers any request that was waiting (AGL-1217).\n // Left alone it would sit `pending` forever, so the staff queue would\n // keep offering a decision on a listing that already has the badge,\n // and the publisher's button would stay disabled as \"already pending\"\n // with nothing to wait for.\n //\n // Only when something is actually waiting: a `verify` on a listing\n // nobody asked about must not invent a request that was never made.\n ...(action === 'verify' &&\n listing.verificationRequest?.state === 'pending'\n ? {\n verificationRequest: {\n ...listing.verificationRequest,\n state: 'granted',\n decidedAt: FieldValue.serverTimestamp(),\n decidedBy: decoded.uid,\n },\n }\n : {}),\n ...(action === 'reject'\n ? { rejectionReason: reason, rejectionCategory: category }\n : {\n rejectionReason: FieldValue.delete(),\n rejectionCategory: FieldValue.delete(),\n }),\n },\n { merge: true },\n )\n // The verdict decides who browse shows the listing to (AGL-3321).\n await refreshListingQueryFields(listingRef)\n\n // Tell the publisher their listing moved (rejections especially).\n if (\n listing.profileId &&\n ['reject', 'list', 'verify', 'delist'].includes(action)\n ) {\n // Publishers are ORGS now (AGL-652), so `profileId` is an org id —\n // writing to users/{profileId}/notifications silently dropped every\n // verdict into a user document nobody reads. Notify the org's managers.\n const publisherOrgId = String(listing.profileId ?? '')\n const publisherSlug = publisherOrgId\n ? ((\n await firestore.collection('orgs').doc(publisherOrgId).get()\n ).get('slug') as string | undefined)\n : undefined\n if (publisherOrgId) {\n const isPrivate = isPrivateListing(listing)\n // One body for the feed and the email (AGL-3432): it names the\n // plugin and what happened to it, and a rejection carries its\n // category and what to fix (AGL-977).\n const verdict = listingVerdictBody({\n action,\n name: String(listing.displayName ?? ''),\n version: String(listing.latestVersion ?? ''),\n offeredVersion: String(listing.latestApprovedVersion ?? ''),\n isPrivate,\n category,\n reason,\n })\n await notifyOrgAdmins(publisherOrgId, {\n type: 'marketplace.review',\n level: action === 'reject' || action === 'delist' ? 'warning' : 'success',\n title:\n action === 'reject'\n ? `\"${listing.displayName}\" was rejected`\n : action === 'delist'\n ? `\"${listing.displayName}\" is back in review`\n : `\"${listing.displayName}\" is now ${nextStatus}`,\n body: verdict,\n orgId: publisherOrgId,\n link: publisherSlug\n ? buildRoute(Route.ORG_MARKETPLACE, {\n orgSlug: publisherSlug,\n })\n : '/',\n }).catch(() => undefined)\n await emailPublisher(\n publisherOrgId,\n action === 'reject'\n ? `${listing.displayName} was rejected — ${rejectionHeadline(\n category,\n reason,\n )}`\n : action === 'delist'\n ? isPrivate\n ? `${listing.displayName} is back in review`\n : `${listing.displayName} was removed from the marketplace`\n : `${listing.displayName} is now ${nextStatus}`,\n verdict,\n {\n frame: {\n plugin: String(listing.displayName ?? ''),\n outcome:\n action === 'reject'\n ? 'Rejected'\n : action === 'delist'\n ? isPrivate\n ? 'Back in review'\n : 'Removed from the marketplace'\n : `Now ${nextStatus}`,\n },\n },\n )\n }\n }\n\n await addAdminAudit(firestore, {\n actorUid: decoded.uid,\n action: `plugins.review.${action}`,\n target: `marketplaceListings/${listingId}`,\n after: { reviewStatus: nextStatus, ...(reason ? { reason } : {}) },\n at: FieldValue.serverTimestamp(),\n })\n\n return Response.json({ ok: true, reviewStatus: nextStatus }, { status: 200 })\n } catch (error) {\n // An unverifiable credential is a 401, not a fault of ours\n // (AGL-1993). Null for anything else, so a real failure keeps its 500.\n const unauthenticated = invalidIdTokenResponse(error)\n if (unauthenticated) return unauthenticated\n console.error(error)\n return Response.json({ error: 'Review action failed' }, { status: 500 })\n }\n}\n\nexport { handler as marketplaceAdminReviews }\n"],"names":["REVOKED_VERSION_REVIEW_STATE","revocationWithdrawsReviewedClaim","shouldStripVerifiedOnTakedown","VERIFIED_STRIPPED_STATUS","checkPluginBundle","isPluginRevoked","newestInstallableVersion","isStoredVerdictCurrent","nextRevocationState","PLUGIN_HOST_ABI_VERSION","PLUGIN_VERIFIER_VERSION","pluginArtifactPath","pluginRequestFromWeb","readPluginContributions","emailUnverifiedResponse","findUserByUidAcrossPools","firebaseAdmin","isImpersonationSession","updateExisting","invalidIdTokenResponse","buildRoute","Route","outstandingChecklistItems","PLUGIN_REVIEW_CHECKLIST","pluginRejectionCategory","rejectionHeadline","rejectionInputError","attestationsForBytes","VERIFICATION_DECLINE_COOLDOWN_DAYS","isPrivateListing","PUBLISHER_AGREEMENT_VERSION","publisherAgreementState","FieldValue","notifyOrgAdmins","refreshListingQueryFields","nameSearchNormalizers","planListQuery","applyListQuery","REVIEW_QUEUE_QUERY","reviewQueueBase","reviewQueueStatusClauses","emailPublisher","dropCachesForListing","addAdminAudit","compareArtifactVersions","REQUIRED_OR_OPTIONAL","Set","map","item","id","ACTIONS","list","verify","reject","delist","unverify","pluginAndVersion","name","version","rejectionReasonText","category","reason","picked","comment","trim","requiresComment","because","label","guidance","versionVerdictBody","input","offeredVersion","liveInstalls","subject","approving","offer","listedNow","filter","Boolean","join","why","listingVerdictBody","isPrivate","action","where","meanwhile","listingDetail","firestore","listingId","requestedVersion","listing","versions","attestationEntries","acceptance","listingRef","collection","doc","snapshot","get","data","Response","json","error","status","versionsSnapshot","orderBy","limit","docs","publishedAt","String","trust","sha256","hostAbi","Number","capabilities","contributes","elements","toDate","toISOString","installCount","activeInstalls","signed","repositoryUrl","reviewState","grandfathered","verification","reviewChecklist","publisherAttestation","publisherId","profileId","publisher","publisherProfile","revocation","pendingFirst","reverse","find","entry","reviewVersion","latestVersion","artifactsBucket","process","env","PLUGIN_ARTIFACTS_BUCKET","reviewEntry","reviewSha","stored","storedIsCurrent","verifier","ok","problems","checks","verifierCached","bytes","app","storage","bucket","file","download","result","toString","declaredNetwork","Array","isArray","network","origin","declaredContributions","set","verifierVersion","checkedAt","serverTimestamp","merge","catch","undefined","Object","values","attesterUid","by","attestedAt","at","attestedBy","found","record","email","displayName","description","verificationRequest","state","requestedAt","declineReason","readme","license","categories","homepageUrl","publisherName","publisherSlug","reviewStatus","rejectionReason","rejectionCategory","priceUsd","hidden","hiddenAt","hiddenReason","revoked","revokedVersions","unpublished","deletedAt","private","visibility","platformHostAbi","checklist","fromEntries","entries","checklistOutstanding","attestation","publisherAgreement","acceptedAt","required","repairLatestApprovedVersion","newest","latestApprovedVersion","delete","updatedAt","REVIEW_QUEUE_PAGE","REVIEW_QUEUE_MAX","queryParam","value","reviewQueue","query","clauses","words","split","asked","Math","floor","pageLimit","isFinite","min","listings","refused","notices","more","queue","listed","read","section","base","plan","search","length","slice","queueDocs","listedDocs","verificationDocs","Promise","all","reviewRow","latest","ref","latestReviewState","verificationRequests","versionDoc","pendingVersions","realmVersions","versionCount","publisherIds","publishers","getAll","exists","handler","request","headers","method","body","rawHeaders","authorization","idToken","startsWith","decoded","auth","verifyIdToken","email_verified","detailId","hideReason","reviewUid","target","targetSnapshot","stripVerified","isListingTarget","hiddenBy","uid","isPlugin","killsInstalledCopies","revocationRef","current","next","type","revokedBy","revokedAt","source","actorUid","subjectUid","after","unverified","versionSnapshot","itemId","checked","has","versionRef","listingSnapshot","outstanding","invalid","reviewedBy","reviewedAt","reviewedSha256","reviewRejectionReason","reviewRejectionCategory","signature","trustGrantedBy","trustGrantedAt","latestVersionReviewState","listsNow","includes","previous","stranded","verdict","level","title","orgId","link","frame","plugin","outcome","revoking","isLatest","revokedVersion","latestVersionReviewStateChanged","decidedAt","decidedBy","actorEmail","scope","before","verificationState","cooldownDays","publisherOrgId","nextStatus","ORG_MARKETPLACE","orgSlug","unauthenticated","console","marketplaceAdminReviews"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../../../../libs/plugins/marketplace/src/lib/server/admin-reviews.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n REVOKED_VERSION_REVIEW_STATE,\n revocationWithdrawsReviewedClaim,\n shouldStripVerifiedOnTakedown,\n VERIFIED_STRIPPED_STATUS,\n} from '../model/plugin-review-status'\nimport {\n checkPluginBundle,\n isPluginRevoked,\n newestInstallableVersion,\n isStoredVerdictCurrent,\n nextRevocationState,\n PLUGIN_HOST_ABI_VERSION,\n PLUGIN_VERIFIER_VERSION,\n pluginArtifactPath,\n pluginRequestFromWeb,\n readPluginContributions,\n type PluginRevocation,\n type StoredBundleVerdict,\n} from '@aglyn/aglyn/server'\nimport {\n emailUnverifiedResponse,\n findUserByUidAcrossPools,\n firebaseAdmin,\n isImpersonationSession,\n updateExisting,\n} from '@aglyn/tenant-data-admin'\nimport { invalidIdTokenResponse } from '@aglyn/tenant-data-admin/server/id-token-refusal'\nimport { buildRoute, Route } from '@aglyn/aglyn/server'\nimport {\n outstandingChecklistItems,\n reviewChecklistFor,\n} from '../model/plugin-review-checklist'\nimport {\n SITE_STARTER_ARTIFACT_TYPE,\n siteStarterFacetsOf,\n} from '@aglyn/aglyn/app-utils/site-starter'\nimport {\n pluginRejectionCategory,\n rejectionHeadline,\n rejectionInputError,\n} from '../model/plugin-rejection-categories'\nimport { attestationsForBytes } from '../model/publisher-attestation'\nimport { VERIFICATION_DECLINE_COOLDOWN_DAYS } from '../model/listing-verification'\nimport { isPrivateListing, listingArtifactType } from '../model/listing-visibility'\nimport {\n PUBLISHER_AGREEMENT_VERSION,\n publisherAgreementState,\n} from '../model/publisher-agreement'\nimport { FieldValue } from 'firebase-admin/firestore'\nimport { notifyOrgAdmins } from '@aglyn/tenant-data-admin'\nimport { refreshListingQueryFields } from './listing-query-fields'\nimport { nameSearchNormalizers } from '@aglyn/aglyn/app-utils/name-search'\nimport {\n type ListQueryPlan,\n planListQuery,\n} from '@aglyn/shared-ui-jsx/const/list-query-plan'\nimport { applyListQuery } from '@aglyn/tenant-data-admin/server/list-query'\nimport {\n REVIEW_QUEUE_QUERY,\n type ReviewQueueSection,\n reviewQueueBase,\n reviewQueueStatusClauses,\n STARTER_REVIEW_QUEUE_QUERY,\n} from '../model/listing-query'\n/*\n * The publisher fan-out lives beside the usage-alert one in `_lib` rather\n * than here. Both are multi-recipient platform sends that have to read the\n * platform suppression list before addressing anybody, and that list has to\n * be reachable by a spec that does not drag the admin SDK in behind a route.\n */\nimport { emailPublisher } from './publisher-review-email'\nimport { dropCachesForListing } from './revoke-cache-drop'\nimport { addAdminAudit } from '@aglyn/tenant-data-admin/server/admin-audit-write'\nimport { compareArtifactVersions } from '../model/update-state'\n\n/**\n * Marketplace review queue (AGL-432) — Strapi Market's two-phase review\n * as staff tooling. GET returns plugin listings awaiting review\n * (submitted/in_review) with the static-verifier verdict re-run against\n * the stored artifact (the same AGL-426 checks the publish API enforced —\n * re-run here so a reviewer sees them without trusting the publish-time\n * result). POST moves a listing through the lifecycle:\n *\n * start-review → in_review list → listed (publicly browsable)\n * verify → verified (✅ badge) reject → rejected (+ reason,\n * notification to the publisher)\n *\n * Realm trust stays a SEPARATE, super-staff grant (`admin-trust.ts`) —\n * listing/verifying here never signs anything. Every action lands in\n * adminAudit.\n */\n/**\n * What staff may do to a site starter (AGL-4049): List it or Reject it, tick\n * its checklist, take it down or restore it. Everything else this route\n * does is about code — versions approved byte for byte, realm trust, a kill\n * switch, the Verified badge — and has nothing to act on in a starter.\n */\nconst STARTER_ACTIONS: ReadonlySet<string> = new Set([\n 'list',\n 'reject',\n 'checklist',\n 'hide',\n 'unhide',\n])\n\nconst ACTIONS: Record<string, string> = {\n 'start-review': 'in_review',\n list: 'listed',\n verify: 'verified',\n reject: 'rejected',\n // Moves BACK down the ladder (AGL-965). Review used to be a one-way\n // ratchet: the only retreats were `reject`, which reads as a verdict on\n // the whole listing and notifies the publisher as such, and takedown,\n // which is the kill switch and stops the plugin in every workspace that\n // already installed it. Neither expresses \"pull it from the marketplace\n // while we look again, without breaking the sites already using it\".\n delist: 'in_review',\n unverify: 'listed',\n}\n\n/*\n * THE WORDS A PUBLISHER READS ABOUT A VERDICT (AGL-3432).\n *\n * The publisher email (`plugin-review-update`) prints only its body, never its\n * subject, and the console feed shows the body under a short title. So every\n * body below opens by naming the plugin, the version when there is one, and\n * what happened to it. A publisher with several plugins cannot tell from\n * \"Your plugin\" which one review means.\n *\n * A private listing never reaches the marketplace (AGL-968), so its copy never\n * says it entered or left it.\n */\n\n/** \"Acme Forms version 1.2.0\", or just the name when no version is known. */\nfunction pluginAndVersion(name: string, version: string): string {\n return version ? `${name} version ${version}` : name\n}\n\n/**\n * Why it was turned down: the category and what to do about it, then the\n * reviewer's comment when there is one (AGL-977).\n *\n * A comment is required only for \"Other\", so every other rejection stands on\n * its category: printing the optional comment alone would leave most\n * rejections with a blank reason and nothing to fix. \"Other\" says nothing by\n * itself, so there the comment is the reason.\n */\nfunction rejectionReasonText(category: string, reason: string): string {\n const picked = pluginRejectionCategory(category)\n const comment = reason.trim()\n if (!picked || picked.requiresComment) return comment\n const because = `${picked.label}. ${picked.guidance}`\n return comment ? `${because}\\n\\nReviewer’s comment: ${comment}` : because\n}\n\n/** The body of a version verdict, for the console notification and the email. */\nfunction versionVerdictBody(input: {\n approving: boolean\n name: string\n version: string\n /** The version new installs receive once this verdict has landed. */\n offeredVersion: string\n /** This approval is what put the listing in the marketplace. */\n listedNow: boolean\n category: string\n reason: string\n liveInstalls: number\n}): string {\n const { name, version, offeredVersion, liveInstalls } = input\n const subject = pluginAndVersion(name, version)\n if (input.approving) {\n // Approving an OLDER version never walks the offer back, so \"now the\n // version new installs receive\" is said only when it became so.\n const offer =\n offeredVersion === version\n ? `It is now the version new installs of ${name} receive. Sites ` +\n 'already running it stay on the version they have until their ' +\n 'owners upgrade.'\n : offeredVersion\n ? `New installs still receive version ${offeredVersion}, the ` +\n 'newest approved version.'\n : ''\n return [\n `${subject} passed review.${offer ? ` ${offer}` : ''}`,\n input.listedNow ? `${name} is now listed in the marketplace.` : '',\n ]\n .filter(Boolean)\n .join('\\n\\n')\n }\n const why = rejectionReasonText(input.category, input.reason)\n return [\n `${subject} was not approved${why ? `: ${why}` : '.'}`,\n `Publishing a new version puts ${name} back in the review queue. The ` +\n 'previously approved version, if any, keeps installing in the meantime.',\n // Pins sitting on these bytes (AGL-1085). The publisher cannot uninstall\n // a version from somebody else's site, so this says what happens rather\n // than telling them to do it.\n liveInstalls > 0\n ? `Version ${version} is still running on ${liveInstalls} ` +\n `site${liveInstalls === 1 ? '' : 's'}. A rejection stops new ` +\n 'installs; it does not remove the version from sites already ' +\n 'running it.'\n : '',\n ]\n .filter(Boolean)\n .join('\\n\\n')\n}\n\n/** The body of a listing verdict, for the console notification and the email. */\nfunction listingVerdictBody(input: {\n action: string\n name: string\n /** The listing's newest bytes, the ones the reviewer read. */\n version: string\n /** The version new installs receive. */\n offeredVersion: string\n isPrivate: boolean\n category: string\n reason: string\n}): string {\n const { name, offeredVersion, isPrivate } = input\n const subject = pluginAndVersion(name, input.version)\n const comment = input.reason.trim()\n const offer = offeredVersion\n ? ` New installs receive version ${offeredVersion}.`\n : ''\n switch (input.action) {\n case 'reject': {\n // A rejection is not a delist, comment or no comment: nobody looks\n // again until the publisher fixes it and sends a new version, so it\n // never borrows the delist's \"while we review it again\".\n const why = rejectionReasonText(input.category, input.reason)\n const where = isPrivate ? 'in review' : 'from the marketplace'\n const meanwhile = isPrivate\n ? 'Sites that already installed it keep working.'\n : `${name} is out of the marketplace while it is rejected; sites ` +\n 'that already installed it keep working.'\n return [\n `${subject} was rejected ${where}${why ? `: ${why}` : '.'}`,\n `${meanwhile} To send it back for review, publish a new version.`,\n ].join('\\n\\n')\n }\n case 'delist':\n return [\n isPrivate\n ? `We moved ${subject} back into review. Sites that already ` +\n 'installed it keep working.'\n : `We removed ${subject} from the marketplace while we review it ` +\n 'again. Sites that already installed it keep working.',\n comment ? `Reviewer’s comment: ${comment}` : '',\n ]\n .filter(Boolean)\n .join('\\n\\n')\n case 'verify':\n return isPrivate\n ? `${name} is now verified.`\n : `${name} is now verified: its marketplace listing shows the ` +\n 'verified badge.'\n default:\n return isPrivate\n ? `${name} passed review. It is a private plugin, so it stays out ` +\n `of the marketplace and only your workspace can install it.${offer}`\n : `${name} passed review and is now listed in the marketplace.${offer}`\n }\n}\n\n/**\n * The body of a site starter's verdict (AGL-4049), for the console\n * notification and the email. A starter is copied into each site created\n * from it, so neither verdict reaches a site that already exists, and the\n * copy never borrows a plugin's installs and versions on offer.\n */\nfunction starterVerdictBody(input: {\n action: 'list' | 'reject'\n name: string\n version: string\n category: string\n reason: string\n}): string {\n const { name } = input\n if (input.action === 'list') {\n return (\n `${name} passed review and is now listed in the marketplace, where ` +\n 'people creating a site can choose it.'\n )\n }\n const why = rejectionReasonText(input.category, input.reason)\n return [\n `${pluginAndVersion(name, input.version)} was rejected${why ? `: ${why}` : '.'}`,\n 'It is not offered to anyone while it is rejected. Sites already ' +\n 'created from it keep everything they have. To send it back for ' +\n 'review, publish it again from its site.',\n ].join('\\n\\n')\n}\n\nconst isRecord = (value: unknown): value is Record<string, any> =>\n !!value && typeof value === 'object' && !Array.isArray(value)\n\n/** A Firestore timestamp as JSON, or `null`. */\nconst isoOf = (value: unknown): string | null =>\n (value as { toDate?: () => Date } | null)?.toDate?.()?.toISOString() ?? null\n\n/** Which terms a publisher org is under (AGL-1077), as the detail pages say it. */\nasync function publisherAgreementOf(\n firestore: FirebaseFirestore.Firestore,\n publisherId: string,\n) {\n const profile = publisherId\n ? await firestore.collection('publisherProfiles').doc(publisherId).get()\n : null\n const acceptance = profile?.get('publisherAgreement') as\n | { version?: string; acceptedBy?: string; acceptedAt?: { toDate?: () => Date } }\n | undefined\n return {\n version: acceptance?.version ?? null,\n acceptedAt: acceptance?.acceptedAt?.toDate?.()?.toISOString() ?? null,\n required: PUBLISHER_AGREEMENT_VERSION,\n state: publisherAgreementState(acceptance),\n }\n}\n\n/**\n * One site starter in full, for its review page (AGL-4049): what a site\n * created from it gets — every page with whether it is published, the layout\n * they sit in, the theme in its shape, the facets a search finds it by, its\n * picture and price — then who publishes it, the site it was published from,\n * its versions, and the starter checklist ticked against the version under\n * review. That version is the one asked for, else the newest: a re-publish\n * is a new version, so a listed starter's newest bytes are always the ones a\n * reviewer reads first.\n */\nasync function starterDetail(\n firestore: FirebaseFirestore.Firestore,\n listingId: string,\n listing: Record<string, any>,\n requestedVersion?: string,\n): Promise<Response> {\n const listingRef = firestore.collection('marketplaceListings').doc(listingId)\n const versionsSnapshot = await listingRef\n .collection('versions')\n .orderBy('publishedAt', 'desc')\n .limit(25)\n .get()\n const versions = versionsSnapshot.docs\n .map((doc) => {\n const data = (doc.data() ?? {}) as Record<string, any>\n const starter = isRecord(data['starter']) ? data['starter'] : {}\n return {\n version: String(doc.id),\n publishedAt: isoOf(data['publishedAt']),\n pages: Array.isArray(starter['screens']) ? starter['screens'].length : 0,\n starter,\n reviewChecklist: (data['reviewChecklist'] ?? null) as Record<\n string,\n { by?: string; version?: string }\n > | null,\n }\n })\n // Numbered by the publish, so newest first however they were read.\n .sort((a, b) => Number(b.version) - Number(a.version))\n const latestVersion = String(listing['latestVersion'] ?? '')\n const reviewVersion =\n (requestedVersion &&\n versions.find((entry) => entry.version === requestedVersion)?.version) ||\n latestVersion\n const review = versions.find((entry) => entry.version === reviewVersion)\n const starter = review?.starter ?? {}\n\n const screens: unknown[] = Array.isArray(starter['screens']) ? starter['screens'] : []\n const pages = screens.filter(isRecord).map((screen) => {\n const slug = typeof screen['slug'] === 'string' && screen['slug'] ? screen['slug'] : null\n return {\n name: String(screen['displayName'] ?? 'Page'),\n slug,\n // A page with no route is unpublished in the site it creates.\n published: Boolean(slug) && screen['published'] !== false,\n }\n })\n const layout = isRecord(starter['layout'])\n ? { name: String(starter['layout']['displayName'] ?? 'Site header and footer') }\n : null\n const storedTheme = isRecord(starter['theme']) ? starter['theme'] : {}\n const theme =\n storedTheme['kind'] === 'builtin'\n ? {\n kind: 'builtin' as const,\n base: String(storedTheme['base'] ?? ''),\n fonts: typeof storedTheme['fonts'] === 'string' ? storedTheme['fonts'] : null,\n brand: {\n light: isRecord(storedTheme['brand']?.light) ? storedTheme['brand'].light : {},\n ...(isRecord(storedTheme['brand']?.dark) ? { dark: storedTheme['brand'].dark } : {}),\n },\n }\n : storedTheme['kind'] === 'full'\n ? { kind: 'full' as const }\n : null\n\n const publisherId = String(listing['profileId'] ?? '')\n const publisher = publisherId\n ? await firestore.collection('orgs').doc(publisherId).get()\n : null\n // The site the pages were captured from, where a reviewer reads them.\n const sourceHostId = String(listing['sourceStarterHostId'] ?? '')\n const source = sourceHostId\n ? await firestore.collection('hosts').doc(sourceHostId).get()\n : null\n const textOf = (value: unknown) => (typeof value === 'string' && value ? value : null)\n\n return Response.json(\n {\n artifactType: SITE_STARTER_ARTIFACT_TYPE,\n listingId,\n displayName: listing['displayName'] ?? listingId,\n description: listing['description'] ?? '',\n category: textOf(listing['category']),\n previewImageUrl: textOf(listing['previewImageUrl']),\n priceUsd: Number(listing['priceUsd'] ?? 0),\n official: listing['official'] === true,\n reviewStatus: listing['reviewStatus'] ?? 'submitted',\n rejectionReason: listing['rejectionReason'] ?? '',\n rejectionCategory: listing['rejectionCategory'] ?? '',\n // The version the last List or Reject was given on, so a listed\n // starter published again since says so.\n reviewedVersion:\n listing['reviewedVersion'] != null ? String(listing['reviewedVersion']) : null,\n hidden: Boolean(listing['hiddenAt']),\n hiddenReason: String(listing['hiddenReason'] ?? ''),\n unpublished: Boolean(listing['deletedAt']),\n createdAt: isoOf(listing['createdAt']),\n latestVersion,\n reviewVersion,\n mode: starter['mode'] === 'ai' ? 'ai' : 'base',\n facets: siteStarterFacetsOf(listing),\n pages,\n layout,\n theme,\n publisherId,\n publisherName: publisher?.get('name') ?? publisherId,\n publisherSlug: publisher?.get('slug') ?? null,\n publisherAgreement: await publisherAgreementOf(firestore, publisherId),\n sourceSite: sourceHostId\n ? {\n hostId: sourceHostId,\n name: textOf(source?.get('displayName')),\n subdomain: textOf(source?.get('subdomain')),\n cname: textOf(source?.get('cname')),\n }\n : null,\n versions: versions.map(({ version, publishedAt, pages: count }) => ({\n version,\n publishedAt,\n pages: count,\n })),\n // Ticks made on another version do not count: a re-publish starts clean.\n checklist: Object.fromEntries(\n Object.entries(review?.reviewChecklist ?? {})\n .filter(([, entry]) => entry?.version === reviewVersion)\n .map(([id, entry]) => [id, { by: entry.by ?? null }]),\n ),\n checklistOutstanding: outstandingChecklistItems(\n review?.reviewChecklist as never,\n reviewVersion,\n SITE_STARTER_ARTIFACT_TYPE,\n ),\n },\n { status: 200 },\n )\n}\n\n/**\n * One listing in full, for the detail page (AGL-959). The index deals in\n * rows; everything a reviewer needs to actually decide — manifest,\n * capabilities, ABI, verifier findings, per-version trust, takedown state —\n * is assembled here rather than smeared across the list payload.\n */\nasync function listingDetail(\n firestore: FirebaseFirestore.Firestore,\n listingId: string,\n requestedVersion?: string,\n): Promise<Response> {\n const listingRef = firestore.collection('marketplaceListings').doc(listingId)\n const snapshot = await listingRef.get()\n const listing = snapshot.data()\n if (!listing) {\n return Response.json({ error: 'Unknown listing' }, { status: 404 })\n }\n // A site starter is pages and a theme, not code (AGL-4049): its page reads\n // what a site created from it gets, and none of the manifest below.\n if (listingArtifactType(listing) === SITE_STARTER_ARTIFACT_TYPE) {\n return starterDetail(firestore, listingId, listing, requestedVersion)\n }\n\n const versionsSnapshot = await listingRef\n .collection('pluginVersions')\n .orderBy('publishedAt', 'desc')\n .limit(25)\n .get()\n const versions = versionsSnapshot.docs.map((doc) => {\n const publishedAt = doc.get('publishedAt')\n return {\n version: String(doc.get('version') ?? doc.id),\n trust: doc.get('trust') ?? null,\n sha256: String(doc.get('sha256') ?? ''),\n hostAbi: Number(doc.get('manifest.hostAbi')) || null,\n capabilities: doc.get('manifest.capabilities') ?? {},\n // What these bytes declare they contribute (AGL-3116); `null` when the\n // version predates the contract and loads under its default.\n contributes: readPluginContributions(doc.get('manifest.contributes')) ?? null,\n // Declared canvas elements (AGL-1031), for THESE bytes. Publisher copy\n // that renders in the customer's element picker and nowhere on the\n // listing page — so without it here, the `element-metadata` criterion\n // asks a reviewer to check text this page never shows (AGL-2486).\n elements: doc.get('manifest.elements') ?? [],\n publishedAt: publishedAt?.toDate?.()?.toISOString() ?? null,\n // Per-version installs (AGL-1036). \"How many workspaces would a revoke\n // actually hit\" is a per-version question, and the listing total shown\n // elsewhere on this page answers a different one.\n installCount: Number(doc.get('installCount') ?? 0),\n activeInstalls: Number(doc.get('activeInstalls') ?? 0),\n signed: Boolean(doc.get('signature')),\n // The repo as declared for THESE bytes (AGL-1076); absent on versions\n // published before it was collected.\n repositoryUrl: String(doc.get('repositoryUrl') ?? ''),\n reviewState: String(doc.get('reviewState') ?? 'pending'),\n grandfathered: Boolean(doc.get('grandfathered')),\n // Server-side only — used to decide whether the verdict below needs\n // recomputing; stripped before the payload goes out.\n verification: doc.get('verification') ?? null,\n reviewChecklist: doc.get('reviewChecklist') ?? null,\n publisherAttestation: doc.get('publisherAttestation') ?? null,\n }\n })\n\n // Publisher is an ORG since AGL-652 — show the name, not the raw id.\n const publisherId = String(listing.profileId ?? '')\n const publisher = publisherId\n ? await firestore.collection('orgs').doc(publisherId).get()\n : null\n\n // Which terms this publisher is actually under (AGL-1077). A reviewer\n // weighing a takedown, a delist, or a revocation is deciding what we are\n // entitled to do — and that is answered by the agreement the ORG accepted,\n // not by the per-version attestation beside it.\n const publisherProfile = publisherId\n ? await firestore.collection('publisherProfiles').doc(publisherId).get()\n : null\n const acceptance = publisherProfile?.get('publisherAgreement') as\n | { version?: string; acceptedBy?: string; acceptedAt?: { toDate?: () => Date } }\n | undefined\n\n // Kill switch, so the page can say whether the plugin is actually stopped\n // rather than only de-listed (AGL-948).\n const revocation = (\n await firestore.collection('revocations').doc(listingId).get()\n ).data()\n\n // The verifier verdict for the version under review (AGL-426), served\n // from the version doc when it is current (AGL-962).\n //\n // `checkPluginBundle` is pure and the artifact is immutable and\n // content-addressed, so a verdict pinned to {sha256, verifierVersion} is\n // exactly as trustworthy as re-running it — and re-running meant\n // downloading up to a megabyte from Storage on EVERY page view. A stored\n // verdict from an older checker, or for different bytes, is ignored.\n // Which version this page is reviewing (AGL-966). Defaults to the oldest\n // version still awaiting a verdict — that is the work — falling back to\n // the latest when everything is decided. A reviewer can pin any version\n // explicitly; the checklist and verifier verdict follow the selection,\n // because both are statements about specific bytes.\n const pendingFirst = [...versions]\n .reverse()\n .find((entry) => entry.reviewState !== 'approved')\n const reviewVersion =\n (requestedVersion &&\n versions.find((entry) => entry.version === requestedVersion)?.version) ||\n pendingFirst?.version ||\n String(listing.latestVersion ?? '')\n const artifactsBucket = process.env.PLUGIN_ARTIFACTS_BUCKET\n const reviewEntry = versions.find((entry) => entry.version === reviewVersion)\n const reviewSha = reviewEntry?.sha256\n const stored = reviewEntry?.verification as StoredBundleVerdict | undefined\n const storedIsCurrent = isStoredVerdictCurrent(stored, reviewSha ?? '')\n\n let verifier: unknown = storedIsCurrent\n ? {\n ok: stored?.ok,\n problems: stored?.problems ?? [],\n // The per-check summary rides along in the stored verdict (AGL-1087)\n // so the page can show what was checked without re-downloading a\n // megabyte of artifact on every view.\n checks: stored?.checks ?? [],\n }\n : null\n let verifierCached = storedIsCurrent\n if (!storedIsCurrent && artifactsBucket && reviewSha) {\n try {\n const [bytes] = await firebaseAdmin\n .app()\n .storage()\n .bucket(artifactsBucket)\n .file(pluginArtifactPath(listingId, reviewVersion, reviewSha))\n .download()\n // The manifest for THESE bytes, so an undeclared network call is a\n // finding rather than a warning (AGL-964). Read from the version doc,\n // never from the listing — capabilities change between versions.\n const result = checkPluginBundle(bytes.toString('utf8'), {\n declaredNetwork: Array.isArray(reviewEntry?.capabilities?.network)\n ? reviewEntry.capabilities.network.map((origin: unknown) =>\n String(origin),\n )\n : [],\n // Compared, never required: a version published before the contract\n // loads under its default, and review must not refuse it for a rule\n // it was never held to.\n declaredContributions: reviewEntry?.contributes ?? null,\n })\n verifier = result\n // Write it back so this sha is verified at most once platform-wide —\n // covers every listing published before the verdict was persisted at\n // publish time, and any version whose checker has since moved on.\n // Best effort: a failed write costs the next reader a re-run, nothing\n // more, so it must never fail the page.\n await listingRef\n .collection('pluginVersions')\n .doc(reviewVersion)\n .set(\n {\n verification: {\n ok: result.ok,\n problems: result.problems,\n checks: result.checks,\n sha256: reviewSha,\n verifierVersion: PLUGIN_VERIFIER_VERSION,\n checkedAt: FieldValue.serverTimestamp(),\n },\n },\n { merge: true },\n )\n .catch(() => undefined)\n } catch {\n verifier = { error: 'artifact unavailable' }\n verifierCached = false\n }\n }\n\n // Who attested, by name (AGL-969). \"A named publisher said this on a date\"\n // is the half that makes a false attestation actionable, and a raw uid\n // names nobody. Best effort — a deleted account must not blank the page.\n const attestationEntries = Object.values(\n (reviewEntry?.publisherAttestation ?? {}) as Record<\n string,\n { by?: string; at?: { toDate?: () => Date }; sha256?: string }\n >,\n ).filter((entry) => entry?.sha256 === reviewSha)\n const attesterUid = attestationEntries.find((entry) => entry.by)?.by\n const attestedAt =\n attestationEntries.find((entry) => entry.at)?.at?.toDate?.()?.toISOString() ??\n null\n let attestedBy: string | null = attesterUid ?? null\n if (attesterUid) {\n try {\n // Across pools (AGL-1122): an SSO attester is invisible to project-level\n // `getUser`, so this fell through to the catch and the review page named\n // the attester by raw uid — indistinguishable from \"account deleted\".\n const found = await findUserByUidAcrossPools(attesterUid)\n if (found) {\n attestedBy =\n found.record.email ?? found.record.displayName ?? attesterUid\n }\n } catch {\n // Account gone — the uid still identifies the statement.\n }\n }\n\n return Response.json(\n {\n artifactType: listingArtifactType(listing),\n listingId,\n displayName: listing.displayName ?? listingId,\n description: listing.description ?? '',\n // The publisher's ask, so the page can offer Decline beside Verify\n // (AGL-1217). Serialized: `decidedAt`/`requestedAt` are Timestamps and\n // this payload crosses JSON.\n verificationRequest: listing.verificationRequest\n ? {\n state: String(listing.verificationRequest.state ?? ''),\n requestedAt:\n listing.verificationRequest.requestedAt?.toDate?.()?.toISOString() ??\n null,\n declineReason: listing.verificationRequest.declineReason ?? null,\n }\n : null,\n readme: listing.readme ?? '',\n license: listing.license ?? '',\n categories: listing.categories ?? [],\n homepageUrl: listing.homepageUrl ?? '',\n // Prefer what the version under review declared (AGL-1076). The\n // listing carries whatever the most recent publish said, and a repo\n // can move between versions — the link a reviewer opens should be the\n // one attested against the bytes in front of them. Falls back to the\n // listing for versions published before this was collected.\n repositoryUrl: reviewEntry?.repositoryUrl || listing.repositoryUrl || '',\n publisherId,\n publisherName: publisher?.get('name') ?? publisherId,\n publisherSlug: publisher?.get('slug') ?? null,\n reviewStatus: listing.reviewStatus ?? 'submitted',\n rejectionReason: listing.rejectionReason ?? '',\n rejectionCategory: listing.rejectionCategory ?? '',\n priceUsd: Number(listing.priceUsd ?? 0),\n latestVersion: String(listing.latestVersion ?? ''),\n // The version the checklist, verifier verdict and approve/reject\n // actions on this payload refer to.\n reviewVersion,\n activeInstalls: Number(listing.activeInstalls ?? 0),\n hidden: Boolean(listing.hiddenAt),\n hiddenReason: String(listing.hiddenReason ?? ''),\n revoked: Boolean(revocation),\n revokedVersions: revocation?.versions ?? null,\n unpublished: Boolean(listing.deletedAt),\n private: listing.visibility === 'private',\n platformHostAbi: PLUGIN_HOST_ABI_VERSION,\n // Where the bundle bytes actually live (AGL-990). Staff-only payload,\n // and a bucket NAME is not a credential — reaching the object still\n // needs a Google account with access. Without it the page cannot build\n // a Cloud console link, and this bucket does not appear in the Firebase\n // console at all, so a reviewer has no way to find it by hand.\n artifactsBucket: artifactsBucket ?? null,\n versions: versions.map(\n // The rest-strip is the point: `verification`, `reviewChecklist` and\n // `publisherAttestation` are named only so they DO NOT reach the\n // client payload, which is what the disable below is for. The\n // duplicate directive that used to sit above `versions.map(` covered\n // a line with nothing unused on it, and this config treats an\n // unused disable as a failure.\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n ({ verification, reviewChecklist, publisherAttestation, ...entry }) => ({\n ...entry,\n // Per-version kill-switch state (AGL-1085), read through the same\n // helper the loaders use so the page cannot disagree with the\n // runtime about whether these bytes are stopped.\n revoked: isPluginRevoked(\n revocation as PluginRevocation | undefined,\n entry.version,\n ),\n }),\n ),\n // Review checklist for the version under review (AGL-963). Ticks made\n // against different bytes do not count, so a republish starts clean.\n checklist: Object.fromEntries(\n Object.entries(\n (reviewEntry?.reviewChecklist ?? {}) as Record<\n string,\n { by?: string; sha256?: string }\n >,\n )\n .filter(([, entry]) => entry?.sha256 === reviewSha)\n .map(([id, entry]) => [id, { by: entry.by ?? null }]),\n ),\n checklistOutstanding: outstandingChecklistItems(\n reviewEntry?.reviewChecklist as never,\n reviewSha ?? '',\n ),\n // What the publisher stated about THESE bytes (AGL-969). Not a review\n // input — a reviewer still checks everything themselves — but it says\n // what was claimed, so a discrepancy is a documented false statement\n // rather than a difference of opinion. Attestations recorded against\n // other bytes are dropped, exactly like staff ticks.\n attestation: attestationsForBytes(\n reviewEntry?.publisherAttestation as never,\n reviewSha ?? '',\n ),\n attestedBy,\n attestedAt,\n // The publisher agreement this ORG is under (AGL-1077). `current` is\n // computed here rather than shipped as a boolean so the page can say\n // \"on an older version\" — which is a different thing from never\n // having accepted, and matters differently to a takedown decision.\n publisherAgreement: {\n version: acceptance?.version ?? null,\n acceptedAt: acceptance?.acceptedAt?.toDate?.()?.toISOString() ?? null,\n required: PUBLISHER_AGREEMENT_VERSION,\n state: publisherAgreementState(acceptance),\n },\n verifier,\n verifierCached,\n verifierVersion: PLUGIN_VERIFIER_VERSION,\n },\n { status: 200 },\n )\n}\n\n/**\n * Re-derive `latestApprovedVersion` from the versions themselves (AGL-2306).\n *\n * The mirror was written on approval only, with a comment saying it \"only ever\n * moves forward\" — true of approvals, and the reason it is there. What nothing\n * did was move it BACK. A version approved and later rejected on re-review, or\n * killed with the per-version switch, left the listing still advertising it:\n * `host-plugins-card` and `model/update-state` read this field to offer\n * \"Update to vX\", and `install-plugin` would then refuse those exact bytes.\n *\n * Contained, because `install-plugin` recomputes approval live and never\n * trusts this field — no unreviewed or revoked bytes could ship — but it is\n * the AGL-1016 guarantee leaking back out through a badge, which is where\n * AGL-966 came in.\n *\n * Recomputed rather than decremented: \"the newest version that is approved AND\n * not revoked\" is a property of the whole set, and stepping it back one at a\n * time is how a mirror drifts in the other direction.\n *\n * Revoked versions are excluded because the offer has to be installable, and\n * `install-plugin` 409s on a revoked pin. That also makes un-revoking restore\n * the offer, which is why this runs on both revoke and unrevoke.\n *\n * Deletes the field when nothing qualifies: an absent mirror reads as \"no\n * update to offer\", while a stale string reads as an update that does not\n * exist.\n */\nasync function repairLatestApprovedVersion(\n listingRef: FirebaseFirestore.DocumentReference,\n revocation: PluginRevocation | null | undefined,\n): Promise<void> {\n const versions = await listingRef\n .collection('pluginVersions')\n .orderBy('publishedAt', 'desc')\n .limit(50)\n .get()\n // The DECISION lives in core (`newestInstallableVersion`), where it is\n // testable without a Firestore double and shared with anything else that\n // has to answer \"what is on offer\". This function is only the query.\n const newest = newestInstallableVersion(\n versions.docs.map((doc) => ({\n version: doc.id,\n reviewState: doc.get('reviewState'),\n })),\n revocation,\n compareArtifactVersions,\n )\n await updateExisting(listingRef, {\n latestApprovedVersion: newest ?? FieldValue.delete(),\n updatedAt: FieldValue.serverTimestamp(),\n })\n}\n\n/** Rows a queue section reads before it says there are more. */\nconst REVIEW_QUEUE_PAGE = 100\n/** The most a reviewer can page the queue out to. */\nconst REVIEW_QUEUE_MAX = 1000\n\nconst queryParam = (value: unknown): string =>\n String(Array.isArray(value) ? (value[0] ?? '') : (value ?? ''))\n\n/**\n * The staff review index (AGL-961), every section on its query (AGL-3321).\n *\n * Four sections, each its own query; three over live plugin listings:\n *\n * - Awaiting review: the newest bytes have no approval. Read from the\n * listing's `latestVersionReviewState` summary, whose `pending` and\n * `rejected` are exactly \"the version's own `reviewState` is not\n * `approved`\" — `revoked` is the one summary value a version keeps its\n * `approved` under, and it is not in `AWAITING_REVIEW_STATES`, so a killed\n * version never re-enters the queue looking unread (AGL-1121).\n * - Listed: `reviewStatus` listed or verified.\n * - Verification requested: the publisher's standing ask (AGL-1217).\n *\n * and one over live site starter listings (AGL-4049), those waiting for\n * review — or, under a Status, those it names — newest first.\n *\n * The Status select and the search (`?status=`, `?q=`) are clauses on every\n * section's query, planned once by `REVIEW_QUEUE_QUERY`; search reads the\n * listing name's `nameTokens`. It used to be matched over one window of a\n * hundred plugin listings, so a plugin past it was in no section at all.\n * `?limit=` pages each section out; a section that holds more than it read\n * says so rather than presenting a short list as the whole queue.\n */\nasync function reviewQueue(\n firestore: FirebaseFirestore.Firestore,\n query: Record<string, unknown>,\n): Promise<Response> {\n const clauses = reviewQueueStatusClauses(queryParam(query['status']))\n const words = queryParam(query['q']).split(/\\s+/).filter(Boolean)\n const asked = Math.floor(Number(queryParam(query['limit'])))\n const pageLimit = Number.isFinite(asked) && asked > 0\n ? Math.min(asked, REVIEW_QUEUE_MAX)\n : REVIEW_QUEUE_PAGE\n const listings = firestore.collection('marketplaceListings')\n\n let refused: ListQueryPlan['refused'] = []\n let notices: string[] = []\n const more: Record<ReviewQueueSection, boolean> = {\n queue: false,\n listed: false,\n verification: false,\n starters: false,\n }\n const read = async (section: ReviewQueueSection) => {\n const base = reviewQueueBase(section, clauses)\n // A Status the section cannot hold: empty by definition, never queried.\n if (!base) return []\n const plan = planListQuery(\n // Site starters read newest first; the plugin sections in id order.\n section === 'starters' ? STARTER_REVIEW_QUEUE_QUERY : REVIEW_QUEUE_QUERY,\n { clauses, search: words, base },\n nameSearchNormalizers,\n )\n refused = plan.refused\n notices = plan.notices\n const snapshot = await applyListQuery(listings, plan)\n .limit(pageLimit + 1)\n .get()\n more[section] = snapshot.docs.length > pageLimit\n return snapshot.docs.slice(0, pageLimit)\n }\n const [queueDocs, listedDocs, verificationDocs, starterDocs] = await Promise.all([\n read('queue'),\n read('listed'),\n read('verification'),\n read('starters'),\n ])\n\n // Rows only (AGL-961). This used to DOWNLOAD every queued bundle to re-run\n // the verifier, so the index paid a Storage round trip per submission\n // before it could paint. The verifier now runs on the detail page, for the\n // one listing being read.\n const reviewRow = async (doc: FirebaseFirestore.QueryDocumentSnapshot) => {\n const listing = doc.data()\n const version = String(listing.latestVersion ?? '')\n const latest = version\n ? await doc.ref.collection('pluginVersions').doc(version).get()\n : null\n return {\n listingId: doc.id,\n displayName: listing.displayName ?? doc.id,\n description: listing.description ?? '',\n license: listing.license ?? '',\n categories: listing.categories ?? [],\n profileId: listing.profileId,\n reviewStatus: listing.reviewStatus ?? 'submitted',\n priceUsd: Number(listing.priceUsd ?? 0),\n version,\n hidden: Boolean(listing.hiddenAt),\n private: listing.visibility === 'private',\n latestReviewState: String(latest?.get('reviewState') ?? 'pending'),\n grandfathered: Boolean(latest?.get('grandfathered')),\n // The publisher's standing ask for the badge (AGL-1217).\n verificationRequest: listing.verificationRequest ?? null,\n }\n }\n const queue = await Promise.all(queueDocs.map(reviewRow))\n // A THIRD section, deliberately not folded into `queue` (AGL-1217).\n // `queue` means \"these bytes have not been read\"; a verification request\n // means \"this publisher asked us to vouch for who they are\". A listing can\n // sit in both at once, and merging them would hide one behind the other.\n const verificationRequests = await Promise.all(verificationDocs.map(reviewRow))\n // Listed/verified plugins with per-version trust (AGL-885): once a listing\n // leaves the queue the Grant/Revoke realm-trust actions used to leave with\n // it. This keeps every listed plugin's version trust state administrable.\n const listed = await Promise.all(\n listedDocs.map(async (doc) => {\n const listing = doc.data()\n const versionsSnapshot = await doc.ref\n .collection('pluginVersions')\n .orderBy('publishedAt', 'desc')\n .limit(10)\n .get()\n const versions = versionsSnapshot.docs.map((versionDoc) => ({\n version: String(versionDoc.get('version') ?? versionDoc.id),\n trust: versionDoc.get('trust') ?? null,\n reviewState: String(versionDoc.get('reviewState') ?? 'pending'),\n }))\n return {\n listingId: doc.id,\n displayName: listing.displayName ?? doc.id,\n reviewStatus: listing.reviewStatus,\n profileId: listing.profileId,\n latestVersion: String(listing.latestVersion ?? ''),\n // Takedown state (AGL-952), so a row shows the current verdict rather\n // than sending a reviewer into the detail page to find out whether\n // the plugin is stopped.\n hidden: Boolean(listing.hiddenAt),\n hiddenReason: String(listing.hiddenReason ?? ''),\n private: listing.visibility === 'private',\n pendingVersions: versions.filter((entry) => entry.reviewState !== 'approved')\n .length,\n // Summarised for the row; the per-version controls live on the detail\n // page (AGL-960).\n realmVersions: versions.filter((entry) => entry.trust === 'realm').length,\n versionCount: versions.length,\n versions,\n }\n }),\n )\n\n // Site starters (AGL-4049), a section of their own: a starter is not code,\n // so a reviewer scans it by its pages, price and when it was submitted\n // rather than a version's review state, and every row is the listing alone.\n const starters = starterDocs.map((doc) => {\n const listing = doc.data()\n return {\n listingId: doc.id,\n displayName: listing.displayName ?? doc.id,\n profileId: listing.profileId,\n reviewStatus: listing.reviewStatus ?? 'submitted',\n priceUsd: Number(listing.priceUsd ?? 0),\n pages: Number(listing.screenCount ?? listing.starterPages ?? 0),\n version: String(listing.latestVersion ?? ''),\n // The version the last verdict was given on, so a listed starter\n // published again since can say so.\n reviewedVersion:\n listing.reviewedVersion != null ? String(listing.reviewedVersion) : null,\n submittedAt: isoOf(listing.createdAt),\n hidden: Boolean(listing.hiddenAt),\n official: listing.official === true,\n }\n })\n\n // Publisher names for scanning (AGL-961) — a listing id tells a reviewer\n // nothing. One batched read for every section.\n const publisherIds = [\n ...new Set(\n [...queue, ...listed, ...verificationRequests, ...starters]\n .map((entry) => String(entry.profileId ?? ''))\n .filter(Boolean),\n ),\n ]\n const publishers: Record<string, string> = {}\n if (publisherIds.length) {\n const docs = await firestore.getAll(\n ...publisherIds.map((id) => firestore.collection('orgs').doc(id)),\n )\n for (const doc of docs) {\n if (doc.exists) publishers[doc.id] = String(doc.get('name') ?? doc.id)\n }\n }\n return Response.json(\n {\n queue,\n listed,\n publishers,\n verificationRequests,\n starters,\n refused,\n notices,\n more,\n limit: pageLimit,\n },\n { status: 200 },\n )\n}\n\nasync function handler(request: Request): Promise<Response> {\n const { method, body, query, headers: rawHeaders } =\n await pluginRequestFromWeb(request)\n const headers = rawHeaders as Partial<Record<string, string>>\n const authorization = headers.authorization ?? ''\n const idToken = authorization.startsWith('Bearer ')\n ? authorization.slice('Bearer '.length)\n : undefined\n if (!idToken) return Response.json({ error: 'Unauthenticated' }, { status: 401 })\n\n try {\n const decoded = await firebaseAdmin.app().auth().verifyIdToken(idToken)\n if (!decoded.email_verified && !isImpersonationSession(decoded)) {\n return emailUnverifiedResponse()\n }\n if (!decoded['staff']) {\n return Response.json({ error: 'Staff only' }, { status: 403 })\n }\n const firestore = firebaseAdmin.app().firestore()\n\n if (method === 'GET') {\n const detailId = String(query['listingId'] ?? '')\n if (detailId) {\n return listingDetail(firestore, detailId, String(query['version'] ?? ''))\n }\n\n return reviewQueue(firestore, query)\n }\n\n if (method !== 'POST') {\n return Response.json({ error: 'Method not allowed' }, { status: 405 })\n }\n const listingId = String(body?.listingId ?? '')\n const action = String(body?.action ?? '')\n\n // A site starter takes only what applies to it (AGL-4049). Read here, ahead\n // of every branch, so a plugin action can never write a plugin's state —\n // a version verdict, a kill switch, a badge — onto a starter.\n const reviewed = listingId\n ? (await firestore.collection('marketplaceListings').doc(listingId).get()).data()\n : undefined\n const isStarter =\n Boolean(reviewed) && listingArtifactType(reviewed ?? {}) === SITE_STARTER_ARTIFACT_TYPE\n if (isStarter && !STARTER_ACTIONS.has(action)) {\n return Response.json(\n { error: 'A site starter is listed or rejected, or taken down; that action is for plugins' },\n { status: 400 },\n )\n }\n\n // Takedown (AGL-658) is separate from the review verdict: it applies to\n // EVERY artifact type, not just plugins, and it must not overwrite a\n // plugin's `reviewStatus` — a hidden plugin that later gets un-hidden\n // should return to the verdict it had, not to square one.\n if (action === 'hide' || action === 'unhide') {\n if (!listingId) {\n return Response.json({ error: 'Missing listingId' }, { status: 400 })\n }\n const hideReason = String(body?.reason ?? '').slice(0, 500)\n if (action === 'hide' && !hideReason.trim()) {\n return Response.json({ error: 'Hiding needs a reason' }, { status: 400 })\n }\n const reviewUid = String(body?.reviewUid ?? '')\n const target = reviewUid\n ? firestore\n .collection('marketplaceListings')\n .doc(listingId)\n .collection('reviews')\n .doc(reviewUid)\n : firestore.collection('marketplaceListings').doc(listingId)\n const targetSnapshot = await target.get()\n if (!targetSnapshot.exists) {\n return Response.json({ error: 'Unknown target' }, { status: 404 })\n }\n // A takedown strips the Verified badge (AGL-1121, decided 2026-08-03).\n //\n // Verified is OUR claim that a human vouched for this publisher. Taking\n // the listing down is us saying the opposite out loud, so the two cannot\n // both stand — a badge surviving a takedown would still be asserting the\n // vouch on the listing page the moment it was restored.\n //\n // Demoted to `listed`, not to `rejected` or `submitted`: the takedown\n // itself is what makes it non-browsable (`hiddenAt`), and rewriting the\n // review verdict would destroy the record of a review that did happen.\n //\n // Restoring deliberately does NOT put the badge back. Re-granting is\n // `verify`, which re-checks the review checklist server-side; an automatic\n // regrant would hand back the badge without anyone re-forming the opinion\n // behind it. Losing it to a takedown is meant to cost a re-review.\n const stripVerified = shouldStripVerifiedOnTakedown({\n action,\n reviewStatus: targetSnapshot.get('reviewStatus'),\n isListingTarget: !reviewUid,\n })\n await target.set(\n reviewUid\n ? { hidden: action === 'hide' }\n : action === 'hide'\n ? {\n hiddenAt: FieldValue.serverTimestamp(),\n hiddenBy: decoded.uid,\n hiddenReason: hideReason,\n ...(stripVerified\n ? { reviewStatus: VERIFIED_STRIPPED_STATUS }\n : {}),\n }\n : {\n hiddenAt: FieldValue.delete(),\n hiddenBy: FieldValue.delete(),\n hiddenReason: FieldValue.delete(),\n },\n { merge: true },\n )\n // A takedown leaves browse for everyone but its publisher, and the\n // queue's Taken down status reads it (AGL-3321).\n if (!reviewUid) await refreshListingQueryFields(target)\n\n // Takedown means takedown (AGL-948). Hiding a PLUGIN listing also\n // writes the kill switch, so one staff action has one outcome\n // instead of leaving the bundle executing in every workspace that\n // already installed it. The realm join blocks on `hiddenAt` too, but\n // the revocation is what the client-side loaders and the public\n // listing-versions endpoint already understand — belt and braces on\n // the one action where a gap means running attacker code.\n const isPlugin =\n !reviewUid &&\n (targetSnapshot.get('artifactType') === 'plugin' ||\n targetSnapshot.get('type') === 'plugin')\n /**\n * An email starter earns the same treatment for the same reason.\n *\n * It is copied on install, so `hiddenAt` alone reaches only the\n * storefront: every tenant who already installed it goes on MAILING it,\n * from the sending domain every other tenant shares. The revocation is\n * what `emailStarterSendBlock` reads at the send, which is the only\n * chokepoint that can still refuse.\n *\n * The five other copied types are deliberately not here. Their content\n * is rendered on the tenant's own site, where `hiddenAt` blocking the\n * next install is the whole of what a takedown can honestly promise —\n * stopping a page from rendering is a different decision, and one nobody\n * has made.\n */\n const killsInstalledCopies =\n isPlugin ||\n (!reviewUid && targetSnapshot.get('artifactType') === 'emailStarter')\n if (killsInstalledCopies) {\n const revocationRef = firestore.collection('revocations').doc(listingId)\n const current = (await revocationRef.get()).data() as\n | PluginRevocation\n | undefined\n // Both transitions go through the shared helper (AGL-1085) so a\n // takedown and a per-version review revocation can coexist. Restoring\n // used to DELETE the doc whenever it was takedown-owned, which also\n // un-revoked any version a reviewer had stopped for an unrelated\n // reason — `reviewVersions` is what survives the round trip.\n const next = nextRevocationState(current, {\n type: action === 'hide' ? 'takedown' : 'restore',\n })\n if (next) {\n await revocationRef.set(\n {\n ...next,\n ...(action === 'hide' ? { reason: hideReason } : {}),\n revokedBy: decoded.uid,\n revokedAt: FieldValue.serverTimestamp(),\n // A restore drops takedown ownership; the field has to go, not\n // merely be overwritten, or the next restore re-deletes.\n ...(action === 'hide' ? {} : { source: FieldValue.delete() }),\n },\n { merge: true },\n )\n } else if (current) {\n await revocationRef.delete()\n }\n // Make the kill switch reach ALREADY-CACHED pages (AGL-1152). The\n // tenant stamps each plugin node with its revocation state at compose\n // time, so without this the bundle we just killed keeps executing on\n // every cached page until it happens to re-render. Best effort: the\n // tenant refuses a revoked plugin at render time regardless.\n //\n // Plugin-only: it walks the plugin INSTALL PINS, which an email\n // starter has none of, and an email is never part of a cached page —\n // its kill is felt at the send, where nothing is cached.\n if (isPlugin) await dropCachesForListing(firestore, listingId)\n // The offer follows the kill switch here too (AGL-2368). AGL-2306\n // taught the per-version revoke and the reject path to repair the\n // mirror and left this one out, so a takedown flattened `versions` to\n // `'all'` — revoking every build — while `latestApprovedVersion` went\n // on naming one. `hiddenAt` hides the listing from browse and blocks\n // the install route, so nothing was installable through it; but a\n // restore clears `hiddenAt` first and the mirror is what the update\n // badges read, and `nextRevocationState` can return a document that\n // still holds a reviewer's per-version revocations. Recomputed from\n // the versions in both directions rather than reasoned about.\n //\n // Named explicitly rather than reusing `target`: `isPlugin` is only\n // true when `reviewUid` is empty, so they are the same document — but\n // that is a fact two conditions apart, and a repair pointed at a\n // review subdocument would write a `latestApprovedVersion` onto it.\n //\n // Plugin-only, unlike the revocation write above: the mirror is\n // recomputed from `pluginVersions`, a collection no other artifact\n // type has, so running it for an email starter would derive \"nothing\n // approved\" from an empty read and write that over the listing.\n if (isPlugin) {\n await repairLatestApprovedVersion(\n firestore.collection('marketplaceListings').doc(listingId),\n next,\n )\n }\n }\n\n await addAdminAudit(firestore, {\n actorUid: decoded.uid,\n action: `plugins.takedown.${action}`,\n target: reviewUid\n ? `marketplaceListings/${listingId}/reviews/${reviewUid}`\n : `marketplaceListings/${listingId}`,\n /*\n * A review document is keyed by its AUTHOR's uid, so hiding one is a\n * staff act against a named person. The target names the review, as\n * it must — but on its own that put the takedown nowhere near the\n * page of the person whose words were removed.\n */\n ...(reviewUid ? { subjectUid: reviewUid } : {}),\n after: {\n hidden: action === 'hide',\n ...(hideReason ? { reason: hideReason } : {}),\n ...(killsInstalledCopies ? { revoked: action === 'hide' } : {}),\n // Recorded because it is a side effect of the takedown rather than\n // something the reviewer asked for, and because getting it back is a\n // re-review rather than an undo.\n ...(stripVerified ? { unverified: true } : {}),\n },\n at: FieldValue.serverTimestamp(),\n })\n\n return Response.json(\n {\n ok: true,\n hidden: action === 'hide',\n revoked: killsInstalledCopies && action === 'hide',\n // The caller shows this — a badge silently disappearing would be\n // worse than one that never existed.\n unverified: stripVerified,\n },\n { status: 200 },\n )\n }\n\n // Review checklist (AGL-963). Ticks are per {version, sha256} and carry\n // who + when, so \"verified\" is a recorded act rather than a click.\n if (action === 'checklist') {\n const version = String(body?.version ?? '')\n const itemId = String(body?.itemId ?? '')\n const checked = body?.checked !== false\n // Each type's own items (AGL-4049): a plugin item means nothing on a\n // starter's pages, and a starter item nothing on a bundle.\n const items = reviewChecklistFor(isStarter ? SITE_STARTER_ARTIFACT_TYPE : 'plugin')\n if (!listingId || !version || !items.some((item) => item.id === itemId)) {\n return Response.json({ error: 'Unknown checklist item' }, { status: 400 })\n }\n // A starter's versions are `versions/{n}`, each written once by the\n // publish that made it; a plugin's are `pluginVersions/{semver}`.\n const versionsCollection = isStarter ? 'versions' : 'pluginVersions'\n const versionRef = firestore\n .collection('marketplaceListings')\n .doc(listingId)\n .collection(versionsCollection)\n .doc(version)\n const versionSnapshot = await versionRef.get()\n if (!versionSnapshot.exists) {\n return Response.json({ error: 'Unknown version' }, { status: 404 })\n }\n // Pins the tick to what it was made against: a plugin's bytes, or the\n // starter version, which a re-publish replaces with the next one.\n const pin = isStarter\n ? { version }\n : { sha256: String(versionSnapshot.get('sha256') ?? '') }\n await versionRef.set(\n {\n reviewChecklist: {\n [itemId]: checked\n ? { by: decoded.uid, at: FieldValue.serverTimestamp(), ...pin }\n : FieldValue.delete(),\n },\n },\n { merge: true },\n )\n // Audited (AGL-971): a checklist tick is the record that a human\n // looked, so it needs the same trail as the verdict it unlocks —\n // including WHICH bytes were looked at.\n await addAdminAudit(firestore, {\n actorUid: decoded.uid,\n action: `plugins.review.checklist.${checked ? 'check' : 'uncheck'}`,\n target: `marketplaceListings/${listingId}/${versionsCollection}/${version}`,\n after: { itemId, checked, ...pin },\n at: FieldValue.serverTimestamp(),\n })\n return Response.json({ ok: true, itemId, checked }, { status: 200 })\n }\n\n // Per-version verdicts (AGL-966). Approval is a statement about bytes,\n // so it lives on the version doc and installs resolve the newest\n // approved one. Listing-level list/verify still exist, but they can no\n // longer ship code past review on their own.\n if (action === 'approve-version' || action === 'reject-version') {\n const version = String(body?.version ?? '')\n const listingRef = firestore.collection('marketplaceListings').doc(listingId)\n const versionRef = listingRef.collection('pluginVersions').doc(version)\n const versionSnapshot = await versionRef.get()\n if (!versionSnapshot.exists) {\n return Response.json({ error: 'Unknown version' }, { status: 404 })\n }\n // The LISTING has to exist too, and the check belongs up here rather\n // than beside the writes that need it (AGL-1766). A version outliving\n // its listing is not hypothetical — Firestore deletes are not\n // recursive, so `pluginVersions` survives whatever removed the parent.\n //\n // The read below used to be `(await listingRef.get()).data() ?? {}`,\n // and that default was not a convenience: it is what made the two\n // mirrors fire. Both of their conditions are TRUE on `{}` —\n // `!['listed','verified'].includes('')` and `previous == null` — so an\n // absent listing was resurrected as `{ reviewStatus: 'listed' }`, i.e.\n // browsable in the marketplace, from a merge-set. (The third mirror,\n // `latestVersionReviewState`, compares `String(latestVersion ?? '')`\n // against a non-empty `version` and is false on `{}` — it could not\n // fire. The pattern is not uniform even inside one block, which is\n // exactly why AGL-1763 could not express this as a lint rule.)\n //\n // Read BEFORE the verdict write, not after it. Refusing must not\n // discard work that already happened (AGL-1760); refusing here happens\n // before anything has, so the reviewer simply retries against a\n // listing that exists. `?? {}` is gone with it — kept, it would have\n // traded a resurrection for an `update()` rejection served as a 500.\n const listingSnapshot = await listingRef.get()\n if (!listingSnapshot.exists) {\n return Response.json({ error: 'Unknown listing' }, { status: 404 })\n }\n const listing = listingSnapshot.data()\n const sha256 = String(versionSnapshot.get('sha256') ?? '')\n const approving = action === 'approve-version'\n if (approving) {\n const outstanding = outstandingChecklistItems(\n versionSnapshot.get('reviewChecklist'),\n sha256,\n )\n if (outstanding.length) {\n return Response.json(\n {\n error: `Review checklist incomplete — ${outstanding.length} required item(s) outstanding for these bytes`,\n outstanding,\n },\n { status: 409 },\n )\n }\n }\n const reason = String(body?.reason ?? '').slice(0, 500)\n // Structured rejection (AGL-977). The category is what makes rejections\n // comparable across reviewers and queryable afterwards; the comment is\n // what makes one actionable. Requiring only free text gave neither.\n const category = String(body?.category ?? '')\n if (!approving) {\n const invalid = rejectionInputError(category, reason)\n if (invalid) return Response.json({ error: invalid }, { status: 400 })\n }\n await versionRef.set(\n {\n reviewState: approving ? 'approved' : 'rejected',\n reviewedBy: decoded.uid,\n reviewedAt: FieldValue.serverTimestamp(),\n // Records WHICH bytes were approved, so a later republish under\n // the same version string can never inherit this verdict.\n reviewedSha256: sha256,\n grandfathered: FieldValue.delete(),\n ...(approving\n ? {\n // Clear a previous rejection's fields on approval, or a\n // version that was rejected and then approved keeps\n // explaining why it was turned down.\n reviewRejectionReason: FieldValue.delete(),\n reviewRejectionCategory: FieldValue.delete(),\n }\n : {\n reviewRejectionReason: reason,\n reviewRejectionCategory: category,\n // REALM TRUST IS WITHDRAWN WITH THE APPROVAL (AGL-2306).\n //\n // `admin-trust` refuses to grant `trust: 'realm'` unless the\n // version is approved — approval gates the grant. Nothing\n // ungated it: the realm load path checks `hiddenAt`, the sha,\n // the signature and the revocation, and never re-reads\n // `reviewState`. So approve → sign → re-review → reject left\n // the version loading IN THE APP REALM, where neither the\n // sandbox iframe nor the plugin-origin CSP is between it and\n // user data, until staff separately reached for the kill\n // switch.\n //\n // The same four fields `admin-trust`'s own revoke branch\n // clears, so there is one shape of \"untrusted\" rather than\n // two. This does NOT stop the bundle running as a sandboxed\n // plugin — that is what the per-version revocation beside\n // this decision is for, and it is deliberately a separate\n // choice (a thin README is the usual rejection, and an\n // unannounced site outage is worse). It withdraws only the\n // privilege that approval was the precondition for.\n trust: FieldValue.delete(),\n signature: FieldValue.delete(),\n trustGrantedBy: FieldValue.delete(),\n trustGrantedAt: FieldValue.delete(),\n }),\n },\n { merge: true },\n )\n\n // A plugin with its first approved version becomes browsable. Later\n // approvals never change listing status — that is the point: an\n // update is reviewed without disturbing what customers already have.\n //\n // The three mirrors below write through `updateExisting` as the second\n // line for the window the check above cannot close — a listing deleted\n // mid-handler. Every payload here is FLAT with no delete sentinel, so\n // the switch is semantically identical to the merge-set it replaces;\n // the `false` return needs no branch, because a listing that is gone by\n // now wants nothing mirrored onto it.\n\n // Mirror this verdict onto the listing for the marketplace (AGL-1121),\n // but ONLY when it is the newest version. Approving an old version\n // must not let the listing claim its newest bytes were reviewed —\n // which is the exact shape of the bug this mirror exists to fix.\n if (String(listing.latestVersion ?? '') === version) {\n await updateExisting(listingRef, {\n latestVersionReviewState: approving ? 'approved' : 'rejected',\n })\n }\n const listsNow =\n approving &&\n !['listed', 'verified'].includes(String(listing.reviewStatus ?? ''))\n if (listsNow) {\n await updateExisting(listingRef, {\n reviewStatus: 'listed',\n updatedAt: FieldValue.serverTimestamp(),\n })\n // Listed is browsable: the browse audience follows (AGL-3321).\n await refreshListingQueryFields(listingRef)\n }\n\n // Denormalise the newest approved version onto the listing (AGL-1016).\n // `pluginVersions` is server-only, so a console showing \"update\n // available\" has nothing else to read — and reading `latestVersion`\n // instead would advertise a version the install route refuses, leaking\n // AGL-966's guarantee back out through a badge.\n //\n // Only ever moves forward: approving an older version after a newer one\n // is a real sequence (a reviewer working through a backlog) and must not\n // walk the offer backwards.\n // What new installs receive once this lands, for the publisher's copy.\n let offeredVersion = String(listing.latestApprovedVersion ?? '')\n if (approving) {\n const previous = listing.latestApprovedVersion\n if (\n previous == null ||\n (compareArtifactVersions(String(previous), version) ?? 0) < 0\n ) {\n await updateExisting(listingRef, {\n latestApprovedVersion: version,\n updatedAt: FieldValue.serverTimestamp(),\n })\n offeredVersion = version\n }\n } else if (String(listing.latestApprovedVersion ?? '') === version) {\n // …and BACK when the version being offered is the one just rejected\n // (AGL-2306). Nothing did this, so a re-review that turned a live\n // version down left the listing advertising it — an \"Update to vX\"\n // for bytes `install-plugin` answers 409 to.\n const revocation = (\n await firestore.collection('revocations').doc(listingId).get()\n ).data() as PluginRevocation | undefined\n await repairLatestApprovedVersion(listingRef, revocation)\n }\n\n await addAdminAudit(firestore, {\n actorUid: decoded.uid,\n action: `plugins.review.version.${approving ? 'approve' : 'reject'}`,\n target: `marketplaceListings/${listingId}/pluginVersions/${version}`,\n after: {\n sha256,\n ...(reason ? { reason } : {}),\n // Both, not one (AGL-971 + AGL-977): the category is what an audit\n // can be counted by, the comment is what makes a single row make\n // sense to a human reading it later.\n ...(category ? { category } : {}),\n },\n at: FieldValue.serverTimestamp(),\n })\n\n // Pins sitting on these exact bytes right now (AGL-1085). Rejecting a\n // version does NOT stop it — the runtime resolves a pin by\n // {version, sha256} and only asks whether it is revoked — so both\n // sides have to be told, and the reviewer needs the number before\n // deciding whether to reach for the kill switch.\n const liveInstalls = Number(versionSnapshot.get('activeInstalls') ?? 0)\n const stranded = !approving && liveInstalls > 0\n\n if (listing.profileId) {\n const verdict = versionVerdictBody({\n approving,\n name: String(listing.displayName ?? ''),\n version,\n offeredVersion,\n listedNow: listsNow && !isPrivateListing(listing),\n category,\n reason,\n liveInstalls,\n })\n await notifyOrgAdmins(String(listing.profileId), {\n type: 'marketplace.review',\n level: approving ? 'success' : 'warning',\n title: approving\n ? `\"${listing.displayName}\" v${version} approved`\n : `\"${listing.displayName}\" v${version} was not approved`,\n body: verdict,\n orgId: String(listing.profileId),\n link: '/',\n }).catch(() => undefined)\n await emailPublisher(\n String(listing.profileId),\n approving\n ? `${listing.displayName} v${version} passed review`\n : `${listing.displayName} v${version} was not approved`,\n verdict,\n {\n frame: {\n plugin: String(listing.displayName ?? ''),\n version,\n outcome: approving ? 'Approved' : 'Not approved',\n },\n },\n )\n }\n\n return Response.json(\n {\n ok: true,\n version,\n reviewState: approving ? 'approved' : 'rejected',\n // Lets the reviewer's confirmation say what it actually did, and\n // offer the kill switch when the bytes are live somewhere.\n liveInstalls,\n stranded,\n },\n { status: 200 },\n )\n }\n\n // Per-version kill switch (AGL-1085). Until now a reviewer's only way to\n // stop live bytes was a listing-wide takedown, which also revokes the\n // approved version customers are happily running and hides the listing.\n // Rejection deliberately stays a verdict rather than a kill: most\n // rejections are a thin README, and an unannounced site outage is worse\n // than the gap. This is the deliberate, adjacent action.\n //\n // This does NOT strip the Verified badge, unlike a takedown (AGL-1121).\n // The two claims are scoped differently and the split is the whole point:\n // Verified says a human vouched for the PUBLISHER and survives version\n // bumps, while the separate \"Reviewed\" chip speaks for THESE bytes and is\n // re-earned per version. Stripping the publisher claim for one bad release\n // would punish an honest mistake, and is not reversible without a full\n // re-review. A takedown is the action that contradicts the publisher claim,\n // and that one does strip it.\n //\n // That reasoning only holds because the BYTES claim is withdrawn instead —\n // which it now is, below. It was not before, and the gap is what made\n // keeping the badge unsafe rather than merely debatable.\n if (action === 'revoke-version' || action === 'unrevoke-version') {\n const version = String(body?.version ?? '')\n if (!listingId || !version) {\n return Response.json(\n { error: 'Listing and version required' },\n { status: 400 },\n )\n }\n const listingRef = firestore.collection('marketplaceListings').doc(listingId)\n const listing = (await listingRef.get()).data() ?? {}\n const revocationRef = firestore.collection('revocations').doc(listingId)\n const current = (await revocationRef.get()).data() as\n | PluginRevocation\n | undefined\n const revoking = action === 'revoke-version'\n const next = nextRevocationState(current, {\n type: revoking ? 'revoke-version' : 'unrevoke-version',\n version,\n })\n if (next) {\n await revocationRef.set(\n {\n ...next,\n reason: String(body?.reason ?? current?.reason ?? '').slice(0, 500),\n revokedBy: decoded.uid,\n revokedAt: FieldValue.serverTimestamp(),\n },\n { merge: true },\n )\n } else {\n await revocationRef.delete()\n }\n // Same reach as the takedown path above (AGL-1152): a per-version\n // revocation changes what every cached page renders, and nothing else\n // drops that HTML.\n await dropCachesForListing(firestore, listingId)\n\n // Withdraw the \"Reviewed\" chip when the bytes we just killed are the ones\n // customers are being offered (AGL-1121).\n //\n // This was ASSUMED to happen already and did not. `latestVersionReviewState`\n // is written only by approve/reject and on publish, so a version approved\n // and later revoked kept `'approved'` — and since a per-version revocation\n // deliberately does NOT hide the listing (that is the whole difference from\n // a takedown), the marketplace went on showing \"A human at Aglyn read these\n // exact bytes\" about bytes we had just stopped from executing. Revocation\n // is not surfaced anywhere else in the browse or listing UI either, so\n // nothing contradicted it.\n //\n // `revoked` rather than `rejected`: it was not turned down in review, it\n // was killed afterwards, and the audit trail should not blur those. Both\n // consumers test against `'approved'`, so this correctly drops the chip and\n // raises the caution alert.\n //\n // Only when it is the LATEST version, because that is what both consumers\n // describe. Revoking an old version says nothing about what is on offer.\n const isLatest = revocationWithdrawsReviewedClaim({\n revokedVersion: version,\n latestVersion: String(listing['latestVersion'] ?? ''),\n })\n if (isLatest) {\n const versionSnapshot = await listingRef\n .collection('pluginVersions')\n .doc(version)\n .get()\n await listingRef.set(\n {\n latestVersionReviewState: revoking\n ? REVOKED_VERSION_REVIEW_STATE\n : // Restoring returns it to whatever the version's own verdict\n // says, rather than assuming `approved` — un-revoking a version\n // that was never approved must not promote it.\n String(versionSnapshot.get('reviewState') ?? 'pending'),\n },\n { merge: true },\n )\n }\n\n // The offer follows the kill switch (AGL-2306). A revoked version is\n // refused by `install-plugin`, so leaving it as `latestApprovedVersion`\n // advertises an update that cannot be taken; un-revoking restores it.\n // Both directions, because both change what is installable.\n await repairLatestApprovedVersion(listingRef, next)\n\n await addAdminAudit(firestore, {\n actorUid: decoded.uid,\n action: `plugins.revocation.${revoking ? 'revoke' : 'restore'}`,\n target: `marketplaceListings/${listingId}/pluginVersions/${version}`,\n after: {\n versions: next?.versions ?? null,\n ...(isLatest ? { latestVersionReviewStateChanged: true } : {}),\n },\n at: FieldValue.serverTimestamp(),\n })\n\n if (listing.profileId) {\n await notifyOrgAdmins(String(listing.profileId), {\n type: 'marketplace.review',\n // Stopped on every site that runs it, which is an outage for them.\n level: revoking ? 'critical' : 'success',\n title: revoking\n ? `\"${listing.displayName}\" v${version} was stopped`\n : `\"${listing.displayName}\" v${version} was allowed to run again`,\n body: revoking\n ? `${pluginAndVersion(String(listing.displayName ?? ''), version)} ` +\n 'has been stopped on every site running it. Those sites now ' +\n 'show a placeholder where the plugin was.'\n : `${pluginAndVersion(String(listing.displayName ?? ''), version)} ` +\n 'is allowed to run again, and sites running it are no longer ' +\n 'blocked.',\n orgId: String(listing.profileId),\n link: '/',\n }).catch(() => undefined)\n }\n\n return Response.json(\n { ok: true, version, revoked: revoking },\n { status: 200 },\n )\n }\n\n // Declining a verification request (AGL-1217). Handled before the ACTIONS\n // lookup because it deliberately has NO `reviewStatus` to move to: the\n // listing stays exactly as live as it was. Refusing a badge is not a\n // verdict on the code, and routing it through the status ladder would\n // make it one.\n if (action === 'decline-verification') {\n const declineReason = String(body?.reason ?? '').trim().slice(0, 500)\n if (!listingId) {\n return Response.json({ error: 'Unknown action' }, { status: 400 })\n }\n // Required, unlike most fields here. The publisher is notified of this\n // and then has to wait out a cooldown before asking again; \"no, and we\n // will not say why, try in a month\" is not a usable answer.\n if (!declineReason) {\n return Response.json(\n { error: 'A reason is required — the publisher is told it' },\n { status: 400 },\n )\n }\n const listingRef = firestore\n .collection('marketplaceListings')\n .doc(listingId)\n const listing = (await listingRef.get()).data()\n if (!listing) {\n return Response.json({ error: 'Unknown listing' }, { status: 404 })\n }\n if (listing.verificationRequest?.state !== 'pending') {\n return Response.json(\n { error: 'No verification request is waiting' },\n { status: 409 },\n )\n }\n await listingRef.set(\n {\n verificationRequest: {\n ...listing.verificationRequest,\n state: 'declined',\n decidedAt: FieldValue.serverTimestamp(),\n decidedBy: decoded.uid,\n declineReason,\n },\n },\n { merge: true },\n )\n /*\n * THE AUDIT ROW THIS BRANCH NEVER WROTE (AGL-2328).\n *\n * Every sibling branch in this file audits, and the file header at the\n * top claims the route is audited. This one mutated\n * `verificationRequest.state`, notified the publisher and started a\n * cooldown, and left no record — so a decline was the one staff\n * decision here that could not be reviewed afterwards, on the action\n * whose reason staff are REQUIRED to type.\n *\n * `reason` uses the audit log's own reason column rather than being\n * buried in `after`, because the audit page renders and exports that\n * column and searches it (AGL-1652) — a why nobody can filter on is a\n * why nobody reads.\n */\n await addAdminAudit(firestore, {\n actorUid: decoded.uid,\n actorEmail: decoded.email ? String(decoded.email) : null,\n action: 'plugins.verification.decline',\n scope: 'marketplace',\n target: `marketplaceListings/${listingId}`,\n before: { verificationState: 'pending' },\n after: {\n verificationState: 'declined',\n cooldownDays: VERIFICATION_DECLINE_COOLDOWN_DAYS,\n },\n reason: declineReason,\n at: FieldValue.serverTimestamp(),\n })\n\n const publisherOrgId = String(listing.profileId ?? '')\n if (publisherOrgId) {\n await notifyOrgAdmins(publisherOrgId, {\n type: 'marketplace.review',\n level: 'warning',\n title: `Verification declined for \"${listing.displayName}\"`,\n // Says plainly that nothing about the listing changed. Without it a\n // publisher reads \"declined\" as a takedown of the plugin itself.\n body:\n `We declined the verified badge for ${listing.displayName}. The ` +\n 'plugin itself is unaffected and stays listed.\\n\\n' +\n `Reason: ${declineReason}\\n\\n` +\n 'You can request verification again in ' +\n `${VERIFICATION_DECLINE_COOLDOWN_DAYS} days.`,\n orgId: publisherOrgId,\n link: '/',\n }).catch(() => undefined)\n }\n return Response.json({ ok: true, state: 'declined' }, { status: 200 })\n }\n\n const nextStatus = ACTIONS[action]\n if (!listingId || !nextStatus) {\n return Response.json({ error: 'Unknown action' }, { status: 400 })\n }\n const reason = String(body?.reason ?? '').slice(0, 500)\n const category = String(body?.category ?? '')\n if (action === 'reject') {\n // A starter is rejected for a starter's reasons (AGL-4049).\n const invalid = rejectionInputError(\n category,\n reason,\n isStarter ? SITE_STARTER_ARTIFACT_TYPE : 'plugin',\n )\n if (invalid) return Response.json({ error: invalid }, { status: 400 })\n }\n\n const listingRef = firestore.collection('marketplaceListings').doc(listingId)\n const listing = (await listingRef.get()).data()\n if (!listing) return Response.json({ error: 'Unknown listing' }, { status: 404 })\n // The version a starter's verdict is given on: its newest, the one a\n // reviewer read (AGL-4049).\n const starterVersion = isStarter ? String(listing.latestVersion ?? '') : ''\n\n // Both gates that expose a plugin to customers require a completed\n // checklist (AGL-963).\n //\n // `list` matters MORE than `verify`, which is easy to get backwards:\n // listing is what makes `isListingBrowsable` true, so it is the moment\n // executable third-party code becomes installable by every workspace.\n // `verify` only adds the badge on top. Gating the badge while leaving\n // listing open would put the ceremony on the weaker action.\n //\n // `start-review` and `reject` stay ungated on purpose: a reviewer must\n // be able to throw something out without first ticking eight boxes\n // about a bundle they have already decided against.\n //\n // A site starter's List waits for the starter checklist, ticked against\n // its newest version (AGL-4049): listing it puts it in front of everyone\n // creating a site.\n if (action === 'verify' || action === 'list') {\n const version = String(listing.latestVersion ?? '')\n const versionSnapshot = await listingRef\n .collection(isStarter ? 'versions' : 'pluginVersions')\n .doc(version)\n .get()\n const outstanding = isStarter\n ? outstandingChecklistItems(\n versionSnapshot.get('reviewChecklist'),\n version,\n SITE_STARTER_ARTIFACT_TYPE,\n )\n : outstandingChecklistItems(\n versionSnapshot.get('reviewChecklist'),\n String(versionSnapshot.get('sha256') ?? ''),\n )\n if (outstanding.length) {\n return Response.json(\n {\n error: `Review checklist incomplete — ${outstanding.length} required item(s) outstanding`,\n outstanding,\n },\n { status: 409 },\n )\n }\n }\n\n await listingRef.set(\n {\n reviewStatus: nextStatus,\n reviewedBy: decoded.uid,\n reviewedAt: FieldValue.serverTimestamp(),\n // Granting the badge answers any request that was waiting (AGL-1217).\n // Left alone it would sit `pending` forever, so the staff queue would\n // keep offering a decision on a listing that already has the badge,\n // and the publisher's button would stay disabled as \"already pending\"\n // with nothing to wait for.\n //\n // Only when something is actually waiting: a `verify` on a listing\n // nobody asked about must not invent a request that was never made.\n ...(action === 'verify' &&\n listing.verificationRequest?.state === 'pending'\n ? {\n verificationRequest: {\n ...listing.verificationRequest,\n state: 'granted',\n decidedAt: FieldValue.serverTimestamp(),\n decidedBy: decoded.uid,\n },\n }\n : {}),\n ...(action === 'reject'\n ? { rejectionReason: reason, rejectionCategory: category }\n : {\n rejectionReason: FieldValue.delete(),\n rejectionCategory: FieldValue.delete(),\n }),\n // Which version a starter's verdict was given on (AGL-4049). A listed\n // starter stays listed when it is published again, so this is how the\n // queue tells a reviewer its newest version came after the review.\n ...(isStarter ? { reviewedVersion: starterVersion } : {}),\n },\n { merge: true },\n )\n // The verdict decides who browse shows the listing to (AGL-3321).\n await refreshListingQueryFields(listingRef)\n\n // Tell the publisher their listing moved (rejections especially).\n if (\n listing.profileId &&\n ['reject', 'list', 'verify', 'delist'].includes(action)\n ) {\n // Publishers are ORGS now (AGL-652), so `profileId` is an org id —\n // writing to users/{profileId}/notifications silently dropped every\n // verdict into a user document nobody reads. Notify the org's managers.\n const publisherOrgId = String(listing.profileId ?? '')\n const publisherSlug = publisherOrgId\n ? ((\n await firestore.collection('orgs').doc(publisherOrgId).get()\n ).get('slug') as string | undefined)\n : undefined\n if (publisherOrgId) {\n const isPrivate = isPrivateListing(listing)\n // One body for the feed and the email (AGL-3432): it names the\n // plugin and what happened to it, and a rejection carries its\n // category and what to fix (AGL-977). A starter's says so as a\n // starter (AGL-4049); its verdicts are only List and Reject.\n const verdict = isStarter\n ? starterVerdictBody({\n action: action === 'reject' ? 'reject' : 'list',\n name: String(listing.displayName ?? ''),\n version: starterVersion,\n category,\n reason,\n })\n : listingVerdictBody({\n action,\n name: String(listing.displayName ?? ''),\n version: String(listing.latestVersion ?? ''),\n offeredVersion: String(listing.latestApprovedVersion ?? ''),\n isPrivate,\n category,\n reason,\n })\n await notifyOrgAdmins(publisherOrgId, {\n type: 'marketplace.review',\n level: action === 'reject' || action === 'delist' ? 'warning' : 'success',\n title:\n action === 'reject'\n ? `\"${listing.displayName}\" was rejected`\n : action === 'delist'\n ? `\"${listing.displayName}\" is back in review`\n : `\"${listing.displayName}\" is now ${nextStatus}`,\n body: verdict,\n orgId: publisherOrgId,\n link: publisherSlug\n ? buildRoute(Route.ORG_MARKETPLACE, {\n orgSlug: publisherSlug,\n })\n : '/',\n }).catch(() => undefined)\n await emailPublisher(\n publisherOrgId,\n action === 'reject'\n ? `${listing.displayName} was rejected — ${rejectionHeadline(\n category,\n reason,\n )}`\n : action === 'delist'\n ? isPrivate\n ? `${listing.displayName} is back in review`\n : `${listing.displayName} was removed from the marketplace`\n : `${listing.displayName} is now ${nextStatus}`,\n verdict,\n {\n frame: isStarter\n ? {\n noun: 'Site starter',\n plugin: String(listing.displayName ?? ''),\n version: starterVersion,\n outcome: action === 'reject' ? 'Rejected' : 'Listed',\n }\n : {\n plugin: String(listing.displayName ?? ''),\n outcome:\n action === 'reject'\n ? 'Rejected'\n : action === 'delist'\n ? isPrivate\n ? 'Back in review'\n : 'Removed from the marketplace'\n : `Now ${nextStatus}`,\n },\n },\n )\n }\n }\n\n await addAdminAudit(firestore, {\n actorUid: decoded.uid,\n action: `plugins.review.${action}`,\n target: `marketplaceListings/${listingId}`,\n after: {\n reviewStatus: nextStatus,\n ...(reason ? { reason } : {}),\n ...(isStarter\n ? { artifactType: SITE_STARTER_ARTIFACT_TYPE, version: starterVersion }\n : {}),\n },\n at: FieldValue.serverTimestamp(),\n })\n\n return Response.json({ ok: true, reviewStatus: nextStatus }, { status: 200 })\n } catch (error) {\n // An unverifiable credential is a 401, not a fault of ours\n // (AGL-1993). Null for anything else, so a real failure keeps its 500.\n const unauthenticated = invalidIdTokenResponse(error)\n if (unauthenticated) return unauthenticated\n console.error(error)\n return Response.json({ error: 'Review action failed' }, { status: 500 })\n }\n}\n\nexport { handler as marketplaceAdminReviews }\n"],"names":["REVOKED_VERSION_REVIEW_STATE","revocationWithdrawsReviewedClaim","shouldStripVerifiedOnTakedown","VERIFIED_STRIPPED_STATUS","checkPluginBundle","isPluginRevoked","newestInstallableVersion","isStoredVerdictCurrent","nextRevocationState","PLUGIN_HOST_ABI_VERSION","PLUGIN_VERIFIER_VERSION","pluginArtifactPath","pluginRequestFromWeb","readPluginContributions","emailUnverifiedResponse","findUserByUidAcrossPools","firebaseAdmin","isImpersonationSession","updateExisting","invalidIdTokenResponse","buildRoute","Route","outstandingChecklistItems","reviewChecklistFor","SITE_STARTER_ARTIFACT_TYPE","siteStarterFacetsOf","pluginRejectionCategory","rejectionHeadline","rejectionInputError","attestationsForBytes","VERIFICATION_DECLINE_COOLDOWN_DAYS","isPrivateListing","listingArtifactType","PUBLISHER_AGREEMENT_VERSION","publisherAgreementState","FieldValue","notifyOrgAdmins","refreshListingQueryFields","nameSearchNormalizers","planListQuery","applyListQuery","REVIEW_QUEUE_QUERY","reviewQueueBase","reviewQueueStatusClauses","STARTER_REVIEW_QUEUE_QUERY","emailPublisher","dropCachesForListing","addAdminAudit","compareArtifactVersions","STARTER_ACTIONS","Set","ACTIONS","list","verify","reject","delist","unverify","pluginAndVersion","name","version","rejectionReasonText","category","reason","picked","comment","trim","requiresComment","because","label","guidance","versionVerdictBody","input","offeredVersion","liveInstalls","subject","approving","offer","listedNow","filter","Boolean","join","why","listingVerdictBody","isPrivate","action","where","meanwhile","starterVerdictBody","isRecord","value","Array","isArray","isoOf","toDate","toISOString","publisherAgreementOf","firestore","publisherId","acceptance","profile","collection","doc","get","acceptedAt","required","state","starterDetail","listingId","listing","requestedVersion","starter","storedTheme","versions","listingRef","versionsSnapshot","orderBy","limit","docs","map","data","String","id","publishedAt","pages","length","reviewChecklist","sort","a","b","Number","latestVersion","reviewVersion","find","entry","review","screens","screen","slug","published","layout","theme","kind","base","fonts","brand","light","dark","publisher","sourceHostId","source","textOf","Response","json","artifactType","displayName","description","previewImageUrl","priceUsd","official","reviewStatus","rejectionReason","rejectionCategory","reviewedVersion","hidden","hiddenReason","unpublished","createdAt","mode","facets","publisherName","publisherSlug","publisherAgreement","sourceSite","hostId","subdomain","cname","count","checklist","Object","fromEntries","entries","by","checklistOutstanding","status","listingDetail","attestationEntries","snapshot","error","trust","sha256","hostAbi","capabilities","contributes","elements","installCount","activeInstalls","signed","repositoryUrl","reviewState","grandfathered","verification","publisherAttestation","profileId","publisherProfile","revocation","pendingFirst","reverse","artifactsBucket","process","env","PLUGIN_ARTIFACTS_BUCKET","reviewEntry","reviewSha","stored","storedIsCurrent","verifier","ok","problems","checks","verifierCached","bytes","app","storage","bucket","file","download","result","toString","declaredNetwork","network","origin","declaredContributions","set","verifierVersion","checkedAt","serverTimestamp","merge","catch","undefined","values","attesterUid","attestedAt","at","attestedBy","found","record","email","verificationRequest","requestedAt","declineReason","readme","license","categories","homepageUrl","hiddenAt","revoked","revokedVersions","deletedAt","private","visibility","platformHostAbi","attestation","repairLatestApprovedVersion","newest","latestApprovedVersion","delete","updatedAt","REVIEW_QUEUE_PAGE","REVIEW_QUEUE_MAX","queryParam","reviewQueue","query","clauses","words","split","asked","Math","floor","pageLimit","isFinite","min","listings","refused","notices","more","queue","listed","starters","read","section","plan","search","slice","queueDocs","listedDocs","verificationDocs","starterDocs","Promise","all","reviewRow","latest","ref","latestReviewState","verificationRequests","versionDoc","pendingVersions","realmVersions","versionCount","screenCount","starterPages","submittedAt","publisherIds","publishers","getAll","exists","handler","request","headers","method","body","rawHeaders","authorization","idToken","startsWith","decoded","auth","verifyIdToken","email_verified","detailId","reviewed","isStarter","has","hideReason","reviewUid","target","targetSnapshot","stripVerified","isListingTarget","hiddenBy","uid","isPlugin","killsInstalledCopies","revocationRef","current","next","type","revokedBy","revokedAt","actorUid","subjectUid","after","unverified","versionSnapshot","itemId","checked","items","some","item","versionsCollection","versionRef","pin","listingSnapshot","outstanding","invalid","reviewedBy","reviewedAt","reviewedSha256","reviewRejectionReason","reviewRejectionCategory","signature","trustGrantedBy","trustGrantedAt","latestVersionReviewState","listsNow","includes","previous","stranded","verdict","level","title","orgId","link","frame","plugin","outcome","revoking","isLatest","revokedVersion","latestVersionReviewStateChanged","decidedAt","decidedBy","actorEmail","scope","before","verificationState","cooldownDays","publisherOrgId","nextStatus","starterVersion","ORG_MARKETPLACE","orgSlug","noun","unauthenticated","console","marketplaceAdminReviews"],"mappings":"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"}
|