@aglyn/plugins-marketplace 1.0.0-beta.151 → 1.0.0-beta.152

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.
@@ -0,0 +1,51 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Aglyn LLC
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ /**
18
+ * Staff trust-signing for realm plugins (AGL-420), served at
19
+ * `/api/marketplace/admin/trust` for this plugin's review queue.
20
+ *
21
+ * It was `apps/console/app/api/admin/sign-plugin/route.ts` until AGL-3080.
22
+ * What moved is everything that is the MARKETPLACE's: `marketplaceListings`
23
+ * is its collection, "a version must have passed review" is its rule, and
24
+ * the fields a grant writes are its documents.
25
+ *
26
+ * ⛔ WHAT DID NOT MOVE IS THE KEY. `PLUGIN_TRUST_PRIVATE_KEY` is deployed to
27
+ * the console and nowhere else — never to a tenant runtime — and this
28
+ * package is published to npm, where a self-hoster generates their own
29
+ * pair. So the signature comes from the shell through
30
+ * `signPluginTrust`, and this route refuses the grant outright when it
31
+ * answers `signed: false`. A `trust: 'realm'` flag written without a
32
+ * signature beside it is the one state the loaders cannot tell from
33
+ * tampering.
34
+ *
35
+ * Granting writes
36
+ * `{trust: 'realm', signature}` onto the listing's version doc, where the
37
+ * signature is the platform Ed25519 key's signature over the version's
38
+ * sha256 hex — the loaders (client blob-import + env-gated server import)
39
+ * verify it against `PLUGIN_TRUST_PUBLIC_KEY` before a byte executes.
40
+ * Super staff only: a realm grant lets marketplace code run in the app
41
+ * realm of every workspace that installs it, the largest blast radius any
42
+ * staff action has. Revoking removes the grant (already-loaded realms
43
+ * pick it up on next load; use `revocations/{listingId}` for the hard
44
+ * kill switch).
45
+ *
46
+ * `PLUGIN_TRUST_PRIVATE_KEY` is the base64 PKCS8 DER Ed25519 private key
47
+ * (pair generated by `tools/scripts/generate-plugin-trust-key.mjs`) —
48
+ * deployed ONLY to the console app, never to tenant runtimes.
49
+ */
50
+ declare function handler(request: Request): Promise<Response>;
51
+ export { handler as marketplaceAdminTrust };
@@ -0,0 +1,190 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Aglyn LLC
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */ import { pluginRequestFromWeb } from "@aglyn/aglyn/server";
17
+ import { signPluginTrust } from "@aglyn/aglyn/plugin-manager/plugin-trust-signing";
18
+ import { emailUnverifiedResponse, firebaseAdmin, isImpersonationSession } from "@aglyn/tenant-data-admin";
19
+ import { invalidIdTokenResponse } from "@aglyn/tenant-data-admin/server/id-token-refusal";
20
+ import { FieldValue } from "firebase-admin/firestore";
21
+ /**
22
+ * Staff trust-signing for realm plugins (AGL-420), served at
23
+ * `/api/marketplace/admin/trust` for this plugin's review queue.
24
+ *
25
+ * It was `apps/console/app/api/admin/sign-plugin/route.ts` until AGL-3080.
26
+ * What moved is everything that is the MARKETPLACE's: `marketplaceListings`
27
+ * is its collection, "a version must have passed review" is its rule, and
28
+ * the fields a grant writes are its documents.
29
+ *
30
+ * ⛔ WHAT DID NOT MOVE IS THE KEY. `PLUGIN_TRUST_PRIVATE_KEY` is deployed to
31
+ * the console and nowhere else — never to a tenant runtime — and this
32
+ * package is published to npm, where a self-hoster generates their own
33
+ * pair. So the signature comes from the shell through
34
+ * `signPluginTrust`, and this route refuses the grant outright when it
35
+ * answers `signed: false`. A `trust: 'realm'` flag written without a
36
+ * signature beside it is the one state the loaders cannot tell from
37
+ * tampering.
38
+ *
39
+ * Granting writes
40
+ * `{trust: 'realm', signature}` onto the listing's version doc, where the
41
+ * signature is the platform Ed25519 key's signature over the version's
42
+ * sha256 hex — the loaders (client blob-import + env-gated server import)
43
+ * verify it against `PLUGIN_TRUST_PUBLIC_KEY` before a byte executes.
44
+ * Super staff only: a realm grant lets marketplace code run in the app
45
+ * realm of every workspace that installs it, the largest blast radius any
46
+ * staff action has. Revoking removes the grant (already-loaded realms
47
+ * pick it up on next load; use `revocations/{listingId}` for the hard
48
+ * kill switch).
49
+ *
50
+ * `PLUGIN_TRUST_PRIVATE_KEY` is the base64 PKCS8 DER Ed25519 private key
51
+ * (pair generated by `tools/scripts/generate-plugin-trust-key.mjs`) —
52
+ * deployed ONLY to the console app, never to tenant runtimes.
53
+ */ async function handler(request) {
54
+ var _headers_authorization;
55
+ const { method, body, headers: rawHeaders } = await pluginRequestFromWeb(request);
56
+ const headers = rawHeaders;
57
+ if (method !== 'POST') {
58
+ return Response.json({
59
+ error: 'Method not allowed'
60
+ }, {
61
+ status: 405
62
+ });
63
+ }
64
+ const authorization = (_headers_authorization = headers.authorization) != null ? _headers_authorization : '';
65
+ const idToken = authorization.startsWith('Bearer ') ? authorization.slice('Bearer '.length) : undefined;
66
+ if (!idToken) return Response.json({
67
+ error: 'Unauthenticated'
68
+ }, {
69
+ status: 401
70
+ });
71
+ try {
72
+ var _decoded_staffRole, _ref, _ref1;
73
+ const decoded = await firebaseAdmin.app().auth().verifyIdToken(idToken);
74
+ if (!decoded.email_verified && !isImpersonationSession(decoded)) {
75
+ return emailUnverifiedResponse();
76
+ }
77
+ if (!decoded['staff']) {
78
+ return Response.json({
79
+ error: 'Staff only'
80
+ }, {
81
+ status: 403
82
+ });
83
+ }
84
+ if (String((_decoded_staffRole = decoded['staffRole']) != null ? _decoded_staffRole : 'support') !== 'super') {
85
+ return Response.json({
86
+ error: 'Requires the super staff role'
87
+ }, {
88
+ status: 403
89
+ });
90
+ }
91
+ const listingId = String((_ref = body == null ? void 0 : body.listingId) != null ? _ref : '');
92
+ const version = String((_ref1 = body == null ? void 0 : body.version) != null ? _ref1 : '');
93
+ const action = (body == null ? void 0 : body.action) === 'revoke' ? 'revoke' : 'grant';
94
+ if (!listingId || !version) {
95
+ return Response.json({
96
+ error: 'Missing listingId or version'
97
+ }, {
98
+ status: 400
99
+ });
100
+ }
101
+ const versionRef = firebaseAdmin.app().firestore().collection('marketplaceListings').doc(listingId).collection('pluginVersions').doc(version);
102
+ const snapshot = await versionRef.get();
103
+ const sha256 = snapshot.get('sha256');
104
+ if (typeof sha256 !== 'string' || !sha256) {
105
+ return Response.json({
106
+ error: 'Unknown plugin version'
107
+ }, {
108
+ status: 404
109
+ });
110
+ }
111
+ // Realm trust is the strongest grant in the platform — it drops a
112
+ // bundle into the app realm, where the sandbox iframe and the manifest
113
+ // CSP no longer stand between it and user data. It cannot be granted to
114
+ // bytes that have not passed review (AGL-966).
115
+ if (action === 'grant' && snapshot.get('reviewState') !== 'approved') {
116
+ var _snapshot_get;
117
+ return Response.json({
118
+ error: 'That version has not passed review — approve it before granting realm trust',
119
+ reviewState: (_snapshot_get = snapshot.get('reviewState')) != null ? _snapshot_get : 'unknown'
120
+ }, {
121
+ status: 409
122
+ });
123
+ }
124
+ if (action === 'grant') {
125
+ /*
126
+ * The shell signs; this decides what is worth signing. A refusal here
127
+ * is final — nothing is written, and the 501 is the same answer an
128
+ * unconfigured deployment has always given, now reached through the
129
+ * contract rather than by reading the key.
130
+ */ const { signed, signature, reason } = await signPluginTrust(sha256);
131
+ if (!signed || !signature) {
132
+ return Response.json({
133
+ error: reason != null ? reason : 'Trust signing is not configured (missing PLUGIN_TRUST_PRIVATE_KEY)'
134
+ }, {
135
+ status: 501
136
+ });
137
+ }
138
+ await versionRef.set({
139
+ trust: 'realm',
140
+ signature,
141
+ trustGrantedBy: decoded.uid,
142
+ trustGrantedAt: FieldValue.serverTimestamp()
143
+ }, {
144
+ merge: true
145
+ });
146
+ } else {
147
+ await versionRef.set({
148
+ trust: FieldValue.delete(),
149
+ signature: FieldValue.delete(),
150
+ trustGrantedBy: FieldValue.delete(),
151
+ trustGrantedAt: FieldValue.delete()
152
+ }, {
153
+ merge: true
154
+ });
155
+ }
156
+ await firebaseAdmin.app().firestore().collection('adminAudit').add({
157
+ actorUid: decoded.uid,
158
+ action: `plugins.trust.${action}`,
159
+ target: `marketplaceListings/${listingId}/pluginVersions/${version}`,
160
+ after: action === 'grant' ? {
161
+ trust: 'realm'
162
+ } : {
163
+ trust: null
164
+ },
165
+ at: FieldValue.serverTimestamp()
166
+ });
167
+ return Response.json({
168
+ ok: true,
169
+ action,
170
+ listingId,
171
+ version
172
+ }, {
173
+ status: 200
174
+ });
175
+ } catch (error) {
176
+ // An unverifiable credential is a 401, not a fault of ours
177
+ // (AGL-1993). Null for anything else, so a real failure keeps its 500.
178
+ const unauthenticated = invalidIdTokenResponse(error);
179
+ if (unauthenticated) return unauthenticated;
180
+ console.error(error);
181
+ return Response.json({
182
+ error: 'Trust signing failed'
183
+ }, {
184
+ status: 500
185
+ });
186
+ }
187
+ }
188
+ export { handler as marketplaceAdminTrust };
189
+
190
+ //# sourceMappingURL=admin-trust.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../../libs/plugins/marketplace/src/lib/server/admin-trust.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 { pluginRequestFromWeb } from '@aglyn/aglyn/server'\nimport { signPluginTrust } from '@aglyn/aglyn/plugin-manager/plugin-trust-signing'\nimport {\n emailUnverifiedResponse,\n firebaseAdmin,\n isImpersonationSession,\n} from '@aglyn/tenant-data-admin'\nimport { invalidIdTokenResponse } from '@aglyn/tenant-data-admin/server/id-token-refusal'\nimport { FieldValue } from 'firebase-admin/firestore'\n\n/**\n * Staff trust-signing for realm plugins (AGL-420), served at\n * `/api/marketplace/admin/trust` for this plugin's review queue.\n *\n * It was `apps/console/app/api/admin/sign-plugin/route.ts` until AGL-3080.\n * What moved is everything that is the MARKETPLACE's: `marketplaceListings`\n * is its collection, \"a version must have passed review\" is its rule, and\n * the fields a grant writes are its documents.\n *\n * ⛔ WHAT DID NOT MOVE IS THE KEY. `PLUGIN_TRUST_PRIVATE_KEY` is deployed to\n * the console and nowhere else — never to a tenant runtime — and this\n * package is published to npm, where a self-hoster generates their own\n * pair. So the signature comes from the shell through\n * `signPluginTrust`, and this route refuses the grant outright when it\n * answers `signed: false`. A `trust: 'realm'` flag written without a\n * signature beside it is the one state the loaders cannot tell from\n * tampering.\n *\n * Granting writes\n * `{trust: 'realm', signature}` onto the listing's version doc, where the\n * signature is the platform Ed25519 key's signature over the version's\n * sha256 hex — the loaders (client blob-import + env-gated server import)\n * verify it against `PLUGIN_TRUST_PUBLIC_KEY` before a byte executes.\n * Super staff only: a realm grant lets marketplace code run in the app\n * realm of every workspace that installs it, the largest blast radius any\n * staff action has. Revoking removes the grant (already-loaded realms\n * pick it up on next load; use `revocations/{listingId}` for the hard\n * kill switch).\n *\n * `PLUGIN_TRUST_PRIVATE_KEY` is the base64 PKCS8 DER Ed25519 private key\n * (pair generated by `tools/scripts/generate-plugin-trust-key.mjs`) —\n * deployed ONLY to the console app, never to tenant runtimes.\n */\nasync function handler(request: Request): Promise<Response> {\n const { method, body, headers: rawHeaders } = await pluginRequestFromWeb(request)\n const headers = rawHeaders as Partial<Record<string, string>>\n if (method !== 'POST') {\n return Response.json({ error: 'Method not allowed' }, { status: 405 })\n }\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 if (String(decoded['staffRole'] ?? 'support') !== 'super') {\n return Response.json({ error: 'Requires the super staff role' }, { status: 403 })\n }\n\n const listingId = String(body?.listingId ?? '')\n const version = String(body?.version ?? '')\n const action = body?.action === 'revoke' ? 'revoke' : 'grant'\n if (!listingId || !version) {\n return Response.json({ error: 'Missing listingId or version' }, { status: 400 })\n }\n\n const versionRef = firebaseAdmin\n .app()\n .firestore()\n .collection('marketplaceListings')\n .doc(listingId)\n .collection('pluginVersions')\n .doc(version)\n const snapshot = await versionRef.get()\n const sha256 = snapshot.get('sha256')\n if (typeof sha256 !== 'string' || !sha256) {\n return Response.json({ error: 'Unknown plugin version' }, { status: 404 })\n }\n\n // Realm trust is the strongest grant in the platform — it drops a\n // bundle into the app realm, where the sandbox iframe and the manifest\n // CSP no longer stand between it and user data. It cannot be granted to\n // bytes that have not passed review (AGL-966).\n if (action === 'grant' && snapshot.get('reviewState') !== 'approved') {\n return Response.json(\n {\n error:\n 'That version has not passed review — approve it before granting realm trust',\n reviewState: snapshot.get('reviewState') ?? 'unknown',\n },\n { status: 409 },\n )\n }\n\n if (action === 'grant') {\n /*\n * The shell signs; this decides what is worth signing. A refusal here\n * is final — nothing is written, and the 501 is the same answer an\n * unconfigured deployment has always given, now reached through the\n * contract rather than by reading the key.\n */\n const { signed, signature, reason } = await signPluginTrust(sha256)\n if (!signed || !signature) {\n return Response.json(\n {\n error:\n reason ??\n 'Trust signing is not configured (missing PLUGIN_TRUST_PRIVATE_KEY)',\n },\n { status: 501 },\n )\n }\n await versionRef.set(\n {\n trust: 'realm',\n signature,\n trustGrantedBy: decoded.uid,\n trustGrantedAt: FieldValue.serverTimestamp(),\n },\n { merge: true },\n )\n } else {\n await versionRef.set(\n {\n trust: FieldValue.delete(),\n signature: FieldValue.delete(),\n trustGrantedBy: FieldValue.delete(),\n trustGrantedAt: FieldValue.delete(),\n },\n { merge: true },\n )\n }\n\n await firebaseAdmin\n .app()\n .firestore()\n .collection('adminAudit')\n .add({\n actorUid: decoded.uid,\n action: `plugins.trust.${action}`,\n target: `marketplaceListings/${listingId}/pluginVersions/${version}`,\n after: action === 'grant' ? { trust: 'realm' } : { trust: null },\n at: FieldValue.serverTimestamp(),\n })\n\n return Response.json({ ok: true, action, listingId, version }, { 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: 'Trust signing failed' }, { status: 500 })\n }\n}\n\nexport { handler as marketplaceAdminTrust }\n"],"names":["pluginRequestFromWeb","signPluginTrust","emailUnverifiedResponse","firebaseAdmin","isImpersonationSession","invalidIdTokenResponse","FieldValue","handler","request","headers","method","body","rawHeaders","Response","json","error","status","authorization","idToken","startsWith","slice","length","undefined","decoded","app","auth","verifyIdToken","email_verified","String","listingId","version","action","versionRef","firestore","collection","doc","snapshot","get","sha256","reviewState","signed","signature","reason","set","trust","trustGrantedBy","uid","trustGrantedAt","serverTimestamp","merge","delete","add","actorUid","target","after","at","ok","unauthenticated","console","marketplaceAdminTrust"],"mappings":"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"}
package/src/lib/server.js CHANGED
@@ -37,6 +37,7 @@ import { previewImageHandler } from "./server/preview-image.js";
37
37
  import { publishHandler } from "./server/publish.js";
38
38
  import { marketplaceAdminReports } from "./server/admin-reports.js";
39
39
  import { marketplaceAdminReviews } from "./server/admin-reviews.js";
40
+ import { marketplaceAdminTrust } from "./server/admin-trust.js";
40
41
  import { reportHandler } from "./server/report.js";
41
42
  import { reviewsHandler } from "./server/reviews.js";
42
43
  import { publisherProfileSaveHandler } from "./server/publisher-profile-save.js";
@@ -124,6 +125,12 @@ import { updateArtifactHandler } from "./server/update-artifact.js";
124
125
  registerPluginApiRoute('marketplace/admin/reviews', {
125
126
  web: marketplaceAdminReviews
126
127
  });
128
+ // Realm trust (AGL-420, moved by AGL-3080). Super-staff only, and the
129
+ // SIGNATURE comes from the shell — the key is the console's and stays
130
+ // there. See `server/admin-trust.ts`.
131
+ registerPluginApiRoute('marketplace/admin/trust', {
132
+ web: marketplaceAdminTrust
133
+ });
127
134
  registerPluginApiRoute('marketplace/reviews', reviewsHandler);
128
135
  registerPluginApiRoute('marketplace/publisher-profile', publisherProfileSaveHandler);
129
136
  registerPluginApiRoute('marketplace/verification-request', verificationRequestHandler);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../libs/plugins/marketplace/src/lib/server.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 registerBillingWebhookHandler,\n registerPluginApiRoute,\n registerCustomFieldType,\n} from '@aglyn/aglyn/server'\n// Its own subpath, never the plugin-manager barrel: what a published page\n// does not need, it must not import.\nimport { registerPluginRouteMetadata } from '@aglyn/aglyn/plugin-manager/plugin-route-metadata'\nimport { BUNDLE_ID } from './constants/bundle-common'\nimport { marketplaceBillingWebhookHandler } from './server/billing-webhook'\nimport { publishPluginHandler } from './server/publish-plugin'\nimport { verificationRequestHandler } from './server/verification-request'\nimport { checkoutHandler } from './server/checkout'\nimport { connectHandler } from './server/connect'\nimport { installHandler } from './server/install'\nimport { installPluginHandler } from './server/install-plugin'\nimport { listingVersionsHandler } from './server/listing-versions'\nimport { RATING_FIELD } from './model/rating-field'\nimport { installDatasetSchemaHandler } from './server/install-dataset-schema'\nimport { installEmailStarterHandler } from './server/install-email-starter'\nimport { installEmailTemplateHandler } from './server/install-email-template'\nimport { installLayoutHandler } from './server/install-layout'\nimport { installTemplateHandler } from './server/install-template'\nimport { installThemeHandler } from './server/install-theme'\nimport { previewImageHandler } from './server/preview-image'\nimport { publishHandler } from './server/publish'\nimport { marketplaceAdminReports } from './server/admin-reports'\nimport { marketplaceAdminReviews } from './server/admin-reviews'\nimport { reportHandler } from './server/report'\nimport { reviewsHandler } from './server/reviews'\nimport { publisherProfileSaveHandler } from './server/publisher-profile-save'\nimport { publishDatasetSchemaHandler } from './server/publish-dataset-schema'\nimport { publishEmailStarterHandler } from './server/publish-email-starter'\nimport { publishEmailTemplateHandler } from './server/publish-email-template'\nimport { publishLayoutHandler } from './server/publish-layout'\nimport { publishTemplateHandler } from './server/publish-template'\nimport { publishThemeHandler } from './server/publish-theme'\nimport { updateArtifactHandler } from './server/update-artifact'\n\n/**\n * Registers the marketplace plugin's console-side API routes (AGL-396):\n * marketplace publish/install of templates and plugins, and the Stripe\n * Connect + checkout flows for paid listings.\n *\n * Upload-bodied routes register here too. The note that used to sit here —\n * that they had to stay as named console routes because the dispatcher\n * \"can't grant per-route bodyParser limits\" — was a Pages Router leftover:\n * `runLegacyHandler` reads the request through the same\n * `pluginRequestFromWeb` a named App Router route would, and imposes no\n * limit of its own. publish-plugin's 8 MB bundle has been going through the\n * dispatcher the whole time.\n */\nexport function registerMarketplaceConsoleApi(): void {\n // Server side of the rating custom field (AGL-434): validators run\n // on import/write paths even when no client loaded the plugin.\n registerCustomFieldType(RATING_FIELD)\n /*\n * What a listing link unfurls as (AGL-876, handed to the platform by\n * AGL-3080).\n *\n * The card used to be built by a hand-written console route with a server\n * layout of its own, which is what kept that route out of the generic\n * plugin route — moving it would have dropped every listing's card with\n * nothing red. The shell asks this instead, so the card survives the move\n * and no console file reads `marketplaceListings` to build a head.\n *\n * One segment and one only: `/{org}/marketplace/{listingId}`. The hub, the\n * publish page and every other address under this route answer `null`,\n * which leaves the shell's own title exactly as it was.\n */\n registerPluginRouteMetadata(\n {\n route: 'marketplace',\n resolve: async (segments) => {\n if (segments.length !== 1) return null\n const { readListingForSocialCard } = await import(\n './server/listing-social-card.server'\n )\n const { listingSocialCard } = await import('./model/listing-social-card')\n return listingSocialCard(await readListingForSocialCard(segments[0]))\n },\n },\n // Named, because this registrar is called directly by the app's server\n // loader rather than from inside a plugin `register` fn, where the\n // loader's owner marker would be set.\n { pluginId: BUNDLE_ID },\n )\n registerPluginApiRoute('marketplace/checkout', checkoutHandler)\n registerPluginApiRoute('marketplace/connect', connectHandler)\n registerPluginApiRoute('marketplace/install', installHandler)\n registerPluginApiRoute('marketplace/install-plugin', installPluginHandler)\n registerPluginApiRoute('marketplace/install-layout', installLayoutHandler)\n registerPluginApiRoute('marketplace/install-template', installTemplateHandler)\n // A theme install DOES change the running site (AGL-1020) — it is the site's\n // appearance — so this route also owns the ways back: `revert` and `reset`.\n registerPluginApiRoute('marketplace/install-theme', installThemeHandler)\n registerPluginApiRoute(\n 'marketplace/install-dataset-schema',\n installDatasetSchemaHandler,\n )\n registerPluginApiRoute(\n 'marketplace/install-email-starter',\n installEmailStarterHandler,\n )\n registerPluginApiRoute(\n 'marketplace/install-email-template',\n installEmailTemplateHandler,\n )\n // Updating a copied artifact is its own route (AGL-1018), not a flag on\n // install: install writes the publisher's version, this one reconciles it\n // with a copy that has diverged and refuses to overwrite silently.\n registerPluginApiRoute('marketplace/update-artifact', updateArtifactHandler)\n registerPluginApiRoute('marketplace/listing-versions', listingVersionsHandler)\n registerPluginApiRoute('marketplace/preview-image', previewImageHandler)\n registerPluginApiRoute('marketplace/publish', publishHandler)\n registerPluginApiRoute('marketplace/report', reportHandler)\n /*\n * The staff end of that button (AGL-2310), moved out of\n * `apps/console/app/api/admin/` by AGL-3080. `web:` because it is a plain\n * fetch from this plugin's own staff page, not a plugin-request handler —\n * the same shape the AI plugin's `ai/admin/*` routes use, and for the same\n * reason: a staff route names no host, so there is no subject to resolve.\n */\n registerPluginApiRoute('marketplace/admin/reports', {\n web: marketplaceAdminReports,\n })\n // The review queue (AGL-432, moved by AGL-3080). Same shape and the same\n // reason: a staff route names no host, so there is no subject to resolve.\n registerPluginApiRoute('marketplace/admin/reviews', {\n web: marketplaceAdminReviews,\n })\n registerPluginApiRoute('marketplace/reviews', reviewsHandler)\n registerPluginApiRoute(\n 'marketplace/publisher-profile',\n publisherProfileSaveHandler,\n )\n registerPluginApiRoute(\n 'marketplace/verification-request',\n verificationRequestHandler,\n )\n registerPluginApiRoute('marketplace/publish-layout', publishLayoutHandler)\n registerPluginApiRoute('marketplace/publish-template', publishTemplateHandler)\n registerPluginApiRoute('marketplace/publish-theme', publishThemeHandler)\n registerPluginApiRoute(\n 'marketplace/publish-dataset-schema',\n publishDatasetSchemaHandler,\n )\n registerPluginApiRoute(\n 'marketplace/publish-email-starter',\n publishEmailStarterHandler,\n )\n registerPluginApiRoute(\n 'marketplace/publish-email-template',\n publishEmailTemplateHandler,\n )\n // Relocated console routes (AGL-418): URLs preserved via the dispatcher.\n registerPluginApiRoute('marketplace/publish-plugin', publishPluginHandler)\n // Marketplace purchases ride the platform Stripe webhook (AGL-418).\n registerBillingWebhookHandler(marketplaceBillingWebhookHandler)\n}\n"],"names":["registerBillingWebhookHandler","registerPluginApiRoute","registerCustomFieldType","registerPluginRouteMetadata","BUNDLE_ID","marketplaceBillingWebhookHandler","publishPluginHandler","verificationRequestHandler","checkoutHandler","connectHandler","installHandler","installPluginHandler","listingVersionsHandler","RATING_FIELD","installDatasetSchemaHandler","installEmailStarterHandler","installEmailTemplateHandler","installLayoutHandler","installTemplateHandler","installThemeHandler","previewImageHandler","publishHandler","marketplaceAdminReports","marketplaceAdminReviews","reportHandler","reviewsHandler","publisherProfileSaveHandler","publishDatasetSchemaHandler","publishEmailStarterHandler","publishEmailTemplateHandler","publishLayoutHandler","publishTemplateHandler","publishThemeHandler","updateArtifactHandler","registerMarketplaceConsoleApi","route","resolve","segments","length","readListingForSocialCard","listingSocialCard","pluginId","web"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../../../libs/plugins/marketplace/src/lib/server.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 registerBillingWebhookHandler,\n registerPluginApiRoute,\n registerCustomFieldType,\n} from '@aglyn/aglyn/server'\n// Its own subpath, never the plugin-manager barrel: what a published page\n// does not need, it must not import.\nimport { registerPluginRouteMetadata } from '@aglyn/aglyn/plugin-manager/plugin-route-metadata'\nimport { BUNDLE_ID } from './constants/bundle-common'\nimport { marketplaceBillingWebhookHandler } from './server/billing-webhook'\nimport { publishPluginHandler } from './server/publish-plugin'\nimport { verificationRequestHandler } from './server/verification-request'\nimport { checkoutHandler } from './server/checkout'\nimport { connectHandler } from './server/connect'\nimport { installHandler } from './server/install'\nimport { installPluginHandler } from './server/install-plugin'\nimport { listingVersionsHandler } from './server/listing-versions'\nimport { RATING_FIELD } from './model/rating-field'\nimport { installDatasetSchemaHandler } from './server/install-dataset-schema'\nimport { installEmailStarterHandler } from './server/install-email-starter'\nimport { installEmailTemplateHandler } from './server/install-email-template'\nimport { installLayoutHandler } from './server/install-layout'\nimport { installTemplateHandler } from './server/install-template'\nimport { installThemeHandler } from './server/install-theme'\nimport { previewImageHandler } from './server/preview-image'\nimport { publishHandler } from './server/publish'\nimport { marketplaceAdminReports } from './server/admin-reports'\nimport { marketplaceAdminReviews } from './server/admin-reviews'\nimport { marketplaceAdminTrust } from './server/admin-trust'\nimport { reportHandler } from './server/report'\nimport { reviewsHandler } from './server/reviews'\nimport { publisherProfileSaveHandler } from './server/publisher-profile-save'\nimport { publishDatasetSchemaHandler } from './server/publish-dataset-schema'\nimport { publishEmailStarterHandler } from './server/publish-email-starter'\nimport { publishEmailTemplateHandler } from './server/publish-email-template'\nimport { publishLayoutHandler } from './server/publish-layout'\nimport { publishTemplateHandler } from './server/publish-template'\nimport { publishThemeHandler } from './server/publish-theme'\nimport { updateArtifactHandler } from './server/update-artifact'\n\n/**\n * Registers the marketplace plugin's console-side API routes (AGL-396):\n * marketplace publish/install of templates and plugins, and the Stripe\n * Connect + checkout flows for paid listings.\n *\n * Upload-bodied routes register here too. The note that used to sit here —\n * that they had to stay as named console routes because the dispatcher\n * \"can't grant per-route bodyParser limits\" — was a Pages Router leftover:\n * `runLegacyHandler` reads the request through the same\n * `pluginRequestFromWeb` a named App Router route would, and imposes no\n * limit of its own. publish-plugin's 8 MB bundle has been going through the\n * dispatcher the whole time.\n */\nexport function registerMarketplaceConsoleApi(): void {\n // Server side of the rating custom field (AGL-434): validators run\n // on import/write paths even when no client loaded the plugin.\n registerCustomFieldType(RATING_FIELD)\n /*\n * What a listing link unfurls as (AGL-876, handed to the platform by\n * AGL-3080).\n *\n * The card used to be built by a hand-written console route with a server\n * layout of its own, which is what kept that route out of the generic\n * plugin route — moving it would have dropped every listing's card with\n * nothing red. The shell asks this instead, so the card survives the move\n * and no console file reads `marketplaceListings` to build a head.\n *\n * One segment and one only: `/{org}/marketplace/{listingId}`. The hub, the\n * publish page and every other address under this route answer `null`,\n * which leaves the shell's own title exactly as it was.\n */\n registerPluginRouteMetadata(\n {\n route: 'marketplace',\n resolve: async (segments) => {\n if (segments.length !== 1) return null\n const { readListingForSocialCard } = await import(\n './server/listing-social-card.server'\n )\n const { listingSocialCard } = await import('./model/listing-social-card')\n return listingSocialCard(await readListingForSocialCard(segments[0]))\n },\n },\n // Named, because this registrar is called directly by the app's server\n // loader rather than from inside a plugin `register` fn, where the\n // loader's owner marker would be set.\n { pluginId: BUNDLE_ID },\n )\n registerPluginApiRoute('marketplace/checkout', checkoutHandler)\n registerPluginApiRoute('marketplace/connect', connectHandler)\n registerPluginApiRoute('marketplace/install', installHandler)\n registerPluginApiRoute('marketplace/install-plugin', installPluginHandler)\n registerPluginApiRoute('marketplace/install-layout', installLayoutHandler)\n registerPluginApiRoute('marketplace/install-template', installTemplateHandler)\n // A theme install DOES change the running site (AGL-1020) — it is the site's\n // appearance — so this route also owns the ways back: `revert` and `reset`.\n registerPluginApiRoute('marketplace/install-theme', installThemeHandler)\n registerPluginApiRoute(\n 'marketplace/install-dataset-schema',\n installDatasetSchemaHandler,\n )\n registerPluginApiRoute(\n 'marketplace/install-email-starter',\n installEmailStarterHandler,\n )\n registerPluginApiRoute(\n 'marketplace/install-email-template',\n installEmailTemplateHandler,\n )\n // Updating a copied artifact is its own route (AGL-1018), not a flag on\n // install: install writes the publisher's version, this one reconciles it\n // with a copy that has diverged and refuses to overwrite silently.\n registerPluginApiRoute('marketplace/update-artifact', updateArtifactHandler)\n registerPluginApiRoute('marketplace/listing-versions', listingVersionsHandler)\n registerPluginApiRoute('marketplace/preview-image', previewImageHandler)\n registerPluginApiRoute('marketplace/publish', publishHandler)\n registerPluginApiRoute('marketplace/report', reportHandler)\n /*\n * The staff end of that button (AGL-2310), moved out of\n * `apps/console/app/api/admin/` by AGL-3080. `web:` because it is a plain\n * fetch from this plugin's own staff page, not a plugin-request handler —\n * the same shape the AI plugin's `ai/admin/*` routes use, and for the same\n * reason: a staff route names no host, so there is no subject to resolve.\n */\n registerPluginApiRoute('marketplace/admin/reports', {\n web: marketplaceAdminReports,\n })\n // The review queue (AGL-432, moved by AGL-3080). Same shape and the same\n // reason: a staff route names no host, so there is no subject to resolve.\n registerPluginApiRoute('marketplace/admin/reviews', {\n web: marketplaceAdminReviews,\n })\n // Realm trust (AGL-420, moved by AGL-3080). Super-staff only, and the\n // SIGNATURE comes from the shell — the key is the console's and stays\n // there. See `server/admin-trust.ts`.\n registerPluginApiRoute('marketplace/admin/trust', {\n web: marketplaceAdminTrust,\n })\n registerPluginApiRoute('marketplace/reviews', reviewsHandler)\n registerPluginApiRoute(\n 'marketplace/publisher-profile',\n publisherProfileSaveHandler,\n )\n registerPluginApiRoute(\n 'marketplace/verification-request',\n verificationRequestHandler,\n )\n registerPluginApiRoute('marketplace/publish-layout', publishLayoutHandler)\n registerPluginApiRoute('marketplace/publish-template', publishTemplateHandler)\n registerPluginApiRoute('marketplace/publish-theme', publishThemeHandler)\n registerPluginApiRoute(\n 'marketplace/publish-dataset-schema',\n publishDatasetSchemaHandler,\n )\n registerPluginApiRoute(\n 'marketplace/publish-email-starter',\n publishEmailStarterHandler,\n )\n registerPluginApiRoute(\n 'marketplace/publish-email-template',\n publishEmailTemplateHandler,\n )\n // Relocated console routes (AGL-418): URLs preserved via the dispatcher.\n registerPluginApiRoute('marketplace/publish-plugin', publishPluginHandler)\n // Marketplace purchases ride the platform Stripe webhook (AGL-418).\n registerBillingWebhookHandler(marketplaceBillingWebhookHandler)\n}\n"],"names":["registerBillingWebhookHandler","registerPluginApiRoute","registerCustomFieldType","registerPluginRouteMetadata","BUNDLE_ID","marketplaceBillingWebhookHandler","publishPluginHandler","verificationRequestHandler","checkoutHandler","connectHandler","installHandler","installPluginHandler","listingVersionsHandler","RATING_FIELD","installDatasetSchemaHandler","installEmailStarterHandler","installEmailTemplateHandler","installLayoutHandler","installTemplateHandler","installThemeHandler","previewImageHandler","publishHandler","marketplaceAdminReports","marketplaceAdminReviews","marketplaceAdminTrust","reportHandler","reviewsHandler","publisherProfileSaveHandler","publishDatasetSchemaHandler","publishEmailStarterHandler","publishEmailTemplateHandler","publishLayoutHandler","publishTemplateHandler","publishThemeHandler","updateArtifactHandler","registerMarketplaceConsoleApi","route","resolve","segments","length","readListingForSocialCard","listingSocialCard","pluginId","web"],"mappings":"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"}