@kuadrant/kuadrant-backstage-plugin-backend 0.0.2-dev-8ec2009 → 0.0.2-dev-90b0d1b

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.
@@ -1 +1 @@
1
- {"version":3,"file":"permissions.cjs.js","sources":["../src/permissions.ts"],"sourcesContent":["import { createPermission } from '@backstage/plugin-permission-common';\n\n/**\n * Permission definitions for the Kuadrant plugin\n *\n * These permissions control access to PlanPolicy, APIProduct, APIKeyRequest,\n * and API key management within the Kuadrant Backstage plugin.\n *\n * Permissions are composable - use them to build custom roles beyond the\n * three reference personas (Platform Engineer, API Owner, API Consumer).\n */\n\n// planpolicy permissions (rate limit tiers)\nexport const kuadrantPlanPolicyCreatePermission = createPermission({\n name: 'kuadrant.planpolicy.create',\n attributes: { action: 'create' },\n});\n\nexport const kuadrantPlanPolicyReadPermission = createPermission({\n name: 'kuadrant.planpolicy.read',\n attributes: { action: 'read' },\n});\n\nexport const kuadrantPlanPolicyUpdatePermission = createPermission({\n name: 'kuadrant.planpolicy.update',\n attributes: { action: 'update' },\n});\n\nexport const kuadrantPlanPolicyDeletePermission = createPermission({\n name: 'kuadrant.planpolicy.delete',\n attributes: { action: 'delete' },\n});\n\nexport const kuadrantPlanPolicyListPermission = createPermission({\n name: 'kuadrant.planpolicy.list',\n attributes: { action: 'read' },\n});\n\n// apiproduct permissions (catalog entries)\nexport const kuadrantApiProductCreatePermission = createPermission({\n name: 'kuadrant.apiproduct.create',\n attributes: { action: 'create' },\n});\n\nexport const kuadrantApiProductReadOwnPermission = createPermission({\n name: 'kuadrant.apiproduct.read.own',\n attributes: { action: 'read' },\n});\n\nexport const kuadrantApiProductReadAllPermission = createPermission({\n name: 'kuadrant.apiproduct.read.all',\n attributes: { action: 'read' },\n});\n\nexport const kuadrantApiProductUpdateOwnPermission = createPermission({\n name: 'kuadrant.apiproduct.update.own',\n attributes: { action: 'update' },\n});\n\nexport const kuadrantApiProductUpdateAllPermission = createPermission({\n name: 'kuadrant.apiproduct.update.all',\n attributes: { action: 'update' },\n});\n\nexport const kuadrantApiProductDeleteOwnPermission = createPermission({\n name: 'kuadrant.apiproduct.delete.own',\n attributes: { action: 'delete' },\n});\n\nexport const kuadrantApiProductDeleteAllPermission = createPermission({\n name: 'kuadrant.apiproduct.delete.all',\n attributes: { action: 'delete' },\n});\n\nexport const kuadrantApiProductListPermission = createPermission({\n name: 'kuadrant.apiproduct.list',\n attributes: { action: 'read' },\n});\n\n// apikeyrequest permissions (access requests)\nexport const kuadrantApiKeyRequestCreatePermission = createPermission({\n name: 'kuadrant.apikeyrequest.create',\n attributes: { action: 'create' },\n resourceType: 'apiproduct',\n});\n\nexport const kuadrantApiKeyRequestReadOwnPermission = createPermission({\n name: 'kuadrant.apikeyrequest.read.own',\n attributes: { action: 'read' },\n});\n\nexport const kuadrantApiKeyRequestReadAllPermission = createPermission({\n name: 'kuadrant.apikeyrequest.read.all',\n attributes: { action: 'read' },\n});\n\nexport const kuadrantApiKeyRequestUpdateOwnPermission = createPermission({\n name: 'kuadrant.apikeyrequest.update.own',\n attributes: { action: 'update' },\n});\n\nexport const kuadrantApiKeyRequestUpdateAllPermission = createPermission({\n name: 'kuadrant.apikeyrequest.update.all',\n attributes: { action: 'update' },\n});\n\nexport const kuadrantApiKeyRequestDeleteOwnPermission = createPermission({\n name: 'kuadrant.apikeyrequest.delete.own',\n attributes: { action: 'delete' },\n});\n\nexport const kuadrantApiKeyRequestDeleteAllPermission = createPermission({\n name: 'kuadrant.apikeyrequest.delete.all',\n attributes: { action: 'delete' },\n});\n\n// api key permissions (managed secrets)\nexport const kuadrantApiKeyReadOwnPermission = createPermission({\n name: 'kuadrant.apikey.read.own',\n attributes: { action: 'read' },\n});\n\nexport const kuadrantApiKeyReadAllPermission = createPermission({\n name: 'kuadrant.apikey.read.all',\n attributes: { action: 'read' },\n});\n\nexport const kuadrantApiKeyDeleteOwnPermission = createPermission({\n name: 'kuadrant.apikey.delete.own',\n attributes: { action: 'delete' },\n});\n\nexport const kuadrantApiKeyDeleteAllPermission = createPermission({\n name: 'kuadrant.apikey.delete.all',\n attributes: { action: 'delete' },\n});\n\n/**\n * All Kuadrant permissions as an array for easy iteration\n */\nexport const kuadrantPermissions = [\n kuadrantPlanPolicyCreatePermission,\n kuadrantPlanPolicyReadPermission,\n kuadrantPlanPolicyUpdatePermission,\n kuadrantPlanPolicyDeletePermission,\n kuadrantPlanPolicyListPermission,\n kuadrantApiProductCreatePermission,\n kuadrantApiProductReadOwnPermission,\n kuadrantApiProductReadAllPermission,\n kuadrantApiProductUpdateOwnPermission,\n kuadrantApiProductUpdateAllPermission,\n kuadrantApiProductDeleteOwnPermission,\n kuadrantApiProductDeleteAllPermission,\n kuadrantApiProductListPermission,\n kuadrantApiKeyRequestCreatePermission,\n kuadrantApiKeyRequestReadOwnPermission,\n kuadrantApiKeyRequestReadAllPermission,\n kuadrantApiKeyRequestUpdateOwnPermission,\n kuadrantApiKeyRequestUpdateAllPermission,\n kuadrantApiKeyRequestDeleteOwnPermission,\n kuadrantApiKeyRequestDeleteAllPermission,\n kuadrantApiKeyReadOwnPermission,\n kuadrantApiKeyReadAllPermission,\n kuadrantApiKeyDeleteOwnPermission,\n kuadrantApiKeyDeleteAllPermission,\n];\n"],"names":["createPermission"],"mappings":"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"}
1
+ {"version":3,"file":"permissions.cjs.js","sources":["../src/permissions.ts"],"sourcesContent":["import { createPermission } from '@backstage/plugin-permission-common';\n\n/**\n * Permission definitions for the Kuadrant plugin\n *\n * These permissions control access to PlanPolicy, APIProduct, APIKeyRequest,\n * and API key management within the Kuadrant Backstage plugin.\n *\n * Permissions are composable - use them to build custom roles beyond the\n * three reference personas (Platform Engineer, API Owner, API Consumer).\n */\n\n// planpolicy permissions (rate limit tiers)\nexport const kuadrantPlanPolicyCreatePermission = createPermission({\n name: 'kuadrant.planpolicy.create',\n attributes: { action: 'create' },\n});\n\nexport const kuadrantPlanPolicyReadPermission = createPermission({\n name: 'kuadrant.planpolicy.read',\n attributes: { action: 'read' },\n});\n\nexport const kuadrantPlanPolicyUpdatePermission = createPermission({\n name: 'kuadrant.planpolicy.update',\n attributes: { action: 'update' },\n});\n\nexport const kuadrantPlanPolicyDeletePermission = createPermission({\n name: 'kuadrant.planpolicy.delete',\n attributes: { action: 'delete' },\n});\n\nexport const kuadrantPlanPolicyListPermission = createPermission({\n name: 'kuadrant.planpolicy.list',\n attributes: { action: 'read' },\n});\n\n// apiproduct permissions (catalog entries)\nexport const kuadrantApiProductCreatePermission = createPermission({\n name: 'kuadrant.apiproduct.create',\n attributes: { action: 'create' },\n});\n\nexport const kuadrantApiProductReadOwnPermission = createPermission({\n name: 'kuadrant.apiproduct.read.own',\n attributes: { action: 'read' },\n});\n\nexport const kuadrantApiProductReadAllPermission = createPermission({\n name: 'kuadrant.apiproduct.read.all',\n attributes: { action: 'read' },\n});\n\nexport const kuadrantApiProductUpdateOwnPermission = createPermission({\n name: 'kuadrant.apiproduct.update.own',\n attributes: { action: 'update' },\n});\n\nexport const kuadrantApiProductUpdateAllPermission = createPermission({\n name: 'kuadrant.apiproduct.update.all',\n attributes: { action: 'update' },\n});\n\nexport const kuadrantApiProductDeleteOwnPermission = createPermission({\n name: 'kuadrant.apiproduct.delete.own',\n attributes: { action: 'delete' },\n});\n\nexport const kuadrantApiProductDeleteAllPermission = createPermission({\n name: 'kuadrant.apiproduct.delete.all',\n attributes: { action: 'delete' },\n});\n\nexport const kuadrantApiProductListPermission = createPermission({\n name: 'kuadrant.apiproduct.list',\n attributes: { action: 'read' },\n});\n\n// apikey request permissions (access requests)\nexport const kuadrantApiKeyRequestCreatePermission = createPermission({\n name: 'kuadrant.apikeyrequest.create',\n attributes: { action: 'create' },\n resourceType: 'apiproduct',\n});\n\nexport const kuadrantApiKeyRequestReadOwnPermission = createPermission({\n name: 'kuadrant.apikeyrequest.read.own',\n attributes: { action: 'read' },\n});\n\nexport const kuadrantApiKeyRequestReadAllPermission = createPermission({\n name: 'kuadrant.apikeyrequest.read.all',\n attributes: { action: 'read' },\n});\n\nexport const kuadrantApiKeyRequestUpdateOwnPermission = createPermission({\n name: 'kuadrant.apikeyrequest.update.own',\n attributes: { action: 'update' },\n});\n\nexport const kuadrantApiKeyRequestUpdateAllPermission = createPermission({\n name: 'kuadrant.apikeyrequest.update.all',\n attributes: { action: 'update' },\n});\n\nexport const kuadrantApiKeyRequestDeleteOwnPermission = createPermission({\n name: 'kuadrant.apikeyrequest.delete.own',\n attributes: { action: 'delete' },\n});\n\nexport const kuadrantApiKeyRequestDeleteAllPermission = createPermission({\n name: 'kuadrant.apikeyrequest.delete.all',\n attributes: { action: 'delete' },\n});\n\n// api key permissions (managed secrets)\nexport const kuadrantApiKeyReadOwnPermission = createPermission({\n name: 'kuadrant.apikey.read.own',\n attributes: { action: 'read' },\n});\n\nexport const kuadrantApiKeyReadAllPermission = createPermission({\n name: 'kuadrant.apikey.read.all',\n attributes: { action: 'read' },\n});\n\nexport const kuadrantApiKeyDeleteOwnPermission = createPermission({\n name: 'kuadrant.apikey.delete.own',\n attributes: { action: 'delete' },\n});\n\nexport const kuadrantApiKeyDeleteAllPermission = createPermission({\n name: 'kuadrant.apikey.delete.all',\n attributes: { action: 'delete' },\n});\n\n/**\n * All Kuadrant permissions as an array for easy iteration\n */\nexport const kuadrantPermissions = [\n kuadrantPlanPolicyCreatePermission,\n kuadrantPlanPolicyReadPermission,\n kuadrantPlanPolicyUpdatePermission,\n kuadrantPlanPolicyDeletePermission,\n kuadrantPlanPolicyListPermission,\n kuadrantApiProductCreatePermission,\n kuadrantApiProductReadOwnPermission,\n kuadrantApiProductReadAllPermission,\n kuadrantApiProductUpdateOwnPermission,\n kuadrantApiProductUpdateAllPermission,\n kuadrantApiProductDeleteOwnPermission,\n kuadrantApiProductDeleteAllPermission,\n kuadrantApiProductListPermission,\n kuadrantApiKeyRequestCreatePermission,\n kuadrantApiKeyRequestReadOwnPermission,\n kuadrantApiKeyRequestReadAllPermission,\n kuadrantApiKeyRequestUpdateOwnPermission,\n kuadrantApiKeyRequestUpdateAllPermission,\n kuadrantApiKeyRequestDeleteOwnPermission,\n kuadrantApiKeyRequestDeleteAllPermission,\n kuadrantApiKeyReadOwnPermission,\n kuadrantApiKeyReadAllPermission,\n kuadrantApiKeyDeleteOwnPermission,\n kuadrantApiKeyDeleteAllPermission,\n];\n"],"names":["createPermission"],"mappings":"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"}
@@ -32,7 +32,7 @@ class APIProductEntityProvider {
32
32
  try {
33
33
  console.log("apiproduct provider: fetching apiproducts from kubernetes");
34
34
  const response = await this.k8sClient.listCustomResources(
35
- "extensions.kuadrant.io",
35
+ "devportal.kuadrant.io",
36
36
  "v1alpha1",
37
37
  "apiproducts"
38
38
  );
@@ -1 +1 @@
1
- {"version":3,"file":"APIProductEntityProvider.cjs.js","sources":["../../src/providers/APIProductEntityProvider.ts"],"sourcesContent":["import { ApiEntity } from '@backstage/catalog-model';\nimport { EntityProvider, EntityProviderConnection } from '@backstage/plugin-catalog-node';\nimport { RootConfigService } from '@backstage/backend-plugin-api';\nimport { KuadrantK8sClient } from '../k8s-client';\n\ninterface APIProduct {\n apiVersion: string;\n kind: string;\n metadata: {\n name: string;\n namespace: string;\n uid: string;\n resourceVersion: string;\n creationTimestamp: string;\n annotations?: Record<string, string>;\n labels?: Record<string, string>;\n };\n spec: {\n displayName?: string;\n description?: string;\n version?: string;\n tags?: string[];\n publishStatus?: 'Draft' | 'Published';\n plans?: Array<{\n tier: string;\n description?: string;\n limits?: any;\n }>;\n planPolicyRef?: {\n name: string;\n namespace: string;\n };\n documentation?: {\n openAPISpec?: string;\n docsURL?: string;\n gitRepository?: string;\n techdocsRef?: string;\n };\n contact?: {\n team?: string;\n email?: string;\n slack?: string;\n };\n };\n status: {\n openapi?: {\n raw?: string;\n lastSyncTime?: string;\n };\n }\n}\n\nexport class APIProductEntityProvider implements EntityProvider {\n private readonly k8sClient: KuadrantK8sClient;\n private connection?: EntityProviderConnection;\n private readonly providerId = 'kuadrant-apiproduct-provider';\n\n constructor(config: RootConfigService) {\n console.log('apiproduct provider: constructor called');\n this.k8sClient = new KuadrantK8sClient(config);\n }\n\n getProviderName(): string {\n return this.providerId;\n }\n\n async connect(connection: EntityProviderConnection): Promise<void> {\n console.log('apiproduct provider: connect called');\n this.connection = connection;\n\n console.log('apiproduct provider: starting initial sync');\n // initial full sync\n await this.refresh();\n\n // schedule periodic refresh (every 30 seconds for development)\n // note: in production, consider 5-10 minutes to reduce api load\n console.log('apiproduct provider: scheduling periodic refresh every 30 seconds');\n setInterval(async () => {\n await this.refresh();\n }, 30 * 1000);\n }\n\n public async refresh(): Promise<void> {\n console.log('apiproduct provider: refresh called');\n if (!this.connection) {\n console.log('apiproduct provider: no connection, skipping refresh');\n return;\n }\n\n try {\n console.log('apiproduct provider: fetching apiproducts from kubernetes');\n // fetch all apiproducts from kubernetes\n const response = await this.k8sClient.listCustomResources(\n 'extensions.kuadrant.io',\n 'v1alpha1',\n 'apiproducts'\n );\n\n const apiProducts = (response.items || []) as APIProduct[];\n console.log(`apiproduct provider: found ${apiProducts.length} apiproducts`);\n\n // filter out Draft API products - only include Published ones\n const publishedProducts = apiProducts.filter(product => {\n const publishStatus = product.spec.publishStatus || 'Draft'; // default to Draft if not specified\n return publishStatus === 'Published';\n });\n console.log(`apiproduct provider: filtered to ${publishedProducts.length} published apiproducts (${apiProducts.length - publishedProducts.length} drafts excluded)`);\n\n // transform apiproducts to backstage api entities\n const entities = publishedProducts\n .map(product => this.transformToEntity(product))\n .filter((entity): entity is ApiEntity => entity !== null);\n console.log(`apiproduct provider: transformed ${entities.length} entities`);\n\n // submit entities to catalog\n console.log('apiproduct provider: submitting entities to catalog');\n await this.connection.applyMutation({\n type: 'full',\n entities: entities.map(entity => ({\n entity,\n locationKey: `kuadrant-apiproduct:${entity.metadata.namespace}/${entity.metadata.name}`,\n })),\n });\n\n console.log(`apiproduct provider: synced ${entities.length} api products`);\n } catch (error) {\n console.error('error refreshing apiproduct entities:', error);\n }\n }\n\n private transformToEntity(product: APIProduct): ApiEntity | null {\n const namespace = product.metadata.namespace || 'default';\n const name = product.metadata.name;\n const displayName = product.spec.displayName || name;\n const description = product.spec.description || `api product: ${displayName}`;\n\n // determine lifecycle from labels or default to production\n const lifecycle = product.metadata.labels?.lifecycle || 'production';\n\n // owner must be set via backstage ownership annotation\n // if missing, skip this apiproduct (created outside backstage or invalid)\n const owner = product.metadata.annotations?.['backstage.io/owner'];\n if (!owner) {\n console.warn(`apiproduct ${namespace}/${name} has no backstage.io/owner annotation, skipping catalog sync`);\n return null;\n }\n\n // build tags from product tags\n const tags = product.spec.tags || [];\n\n // OpenAPI spec URL\n const definition = product.status?.openapi?.raw ? `${product.status.openapi.raw}`\n : `# no openapi spec configured\n openapi: 3.0.0\n info:\n title: ${displayName}\n version: ${product.spec.version || '1.0.0'}\n description: ${description}\n `;\n\n // create entity with proper backstage structure\n const entity: ApiEntity = {\n apiVersion: 'backstage.io/v1alpha1',\n kind: 'API',\n metadata: {\n name: `${name}`,\n namespace: 'default',\n title: displayName,\n description,\n annotations: {\n 'backstage.io/managed-by-location': `kuadrant:${namespace}/${name}`,\n 'backstage.io/managed-by-origin-location': `kuadrant:${namespace}/${name}`,\n 'backstage.io/orphan-strategy': 'keep',\n 'kuadrant.io/namespace': namespace,\n 'kuadrant.io/apiproduct': name,\n // add httproute annotation if we can infer it (usually same as apiproduct name without -api suffix)\n 'kuadrant.io/httproute': name.endsWith('-api') ? name.slice(0, -4) : name,\n ...(product.spec.documentation?.openAPISpec && {\n 'kuadrant.io/openapi-spec-url': product.spec.documentation.openAPISpec,\n }),\n ...(product.spec.documentation?.docsURL && {\n 'kuadrant.io/docs-url': product.spec.documentation.docsURL,\n }),\n ...(product.spec.documentation?.gitRepository && {\n 'backstage.io/source-location': `url:${product.spec.documentation.gitRepository}`,\n }),\n ...(product.spec.documentation?.techdocsRef && {\n 'backstage.io/techdocs-ref': product.spec.documentation.techdocsRef,\n }),\n ...(product.spec.contact?.email && {\n 'kuadrant.io/contact-email': product.spec.contact.email,\n }),\n ...(product.spec.contact?.slack && {\n 'kuadrant.io/contact-slack': product.spec.contact.slack,\n }),\n },\n tags: [...tags, 'kuadrant', 'apiproduct'],\n labels: {\n 'kuadrant.io/synced': 'true',\n ...(product.metadata.labels || {}),\n },\n },\n spec: {\n type: 'openapi',\n lifecycle,\n owner,\n definition: definition,\n },\n };\n\n return entity;\n }\n}\n"],"names":["KuadrantK8sClient"],"mappings":"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"}
1
+ {"version":3,"file":"APIProductEntityProvider.cjs.js","sources":["../../src/providers/APIProductEntityProvider.ts"],"sourcesContent":["import { ApiEntity } from '@backstage/catalog-model';\nimport { EntityProvider, EntityProviderConnection } from '@backstage/plugin-catalog-node';\nimport { RootConfigService } from '@backstage/backend-plugin-api';\nimport { KuadrantK8sClient } from '../k8s-client';\n\ninterface APIProduct {\n apiVersion: string;\n kind: string;\n metadata: {\n name: string;\n namespace: string;\n uid: string;\n resourceVersion: string;\n creationTimestamp: string;\n annotations?: Record<string, string>;\n labels?: Record<string, string>;\n };\n spec: {\n displayName?: string;\n description?: string;\n version?: string;\n tags?: string[];\n publishStatus?: 'Draft' | 'Published';\n plans?: Array<{\n tier: string;\n description?: string;\n limits?: any;\n }>;\n planPolicyRef?: {\n name: string;\n namespace: string;\n };\n documentation?: {\n openAPISpec?: string;\n docsURL?: string;\n gitRepository?: string;\n techdocsRef?: string;\n };\n contact?: {\n team?: string;\n email?: string;\n slack?: string;\n };\n };\n status: {\n openapi?: {\n raw?: string;\n lastSyncTime?: string;\n };\n }\n}\n\nexport class APIProductEntityProvider implements EntityProvider {\n private readonly k8sClient: KuadrantK8sClient;\n private connection?: EntityProviderConnection;\n private readonly providerId = 'kuadrant-apiproduct-provider';\n\n constructor(config: RootConfigService) {\n console.log('apiproduct provider: constructor called');\n this.k8sClient = new KuadrantK8sClient(config);\n }\n\n getProviderName(): string {\n return this.providerId;\n }\n\n async connect(connection: EntityProviderConnection): Promise<void> {\n console.log('apiproduct provider: connect called');\n this.connection = connection;\n\n console.log('apiproduct provider: starting initial sync');\n // initial full sync\n await this.refresh();\n\n // schedule periodic refresh (every 30 seconds for development)\n // note: in production, consider 5-10 minutes to reduce api load\n console.log('apiproduct provider: scheduling periodic refresh every 30 seconds');\n setInterval(async () => {\n await this.refresh();\n }, 30 * 1000);\n }\n\n public async refresh(): Promise<void> {\n console.log('apiproduct provider: refresh called');\n if (!this.connection) {\n console.log('apiproduct provider: no connection, skipping refresh');\n return;\n }\n\n try {\n console.log('apiproduct provider: fetching apiproducts from kubernetes');\n // fetch all apiproducts from kubernetes\n const response = await this.k8sClient.listCustomResources(\n 'devportal.kuadrant.io',\n 'v1alpha1',\n 'apiproducts'\n );\n\n const apiProducts = (response.items || []) as APIProduct[];\n console.log(`apiproduct provider: found ${apiProducts.length} apiproducts`);\n\n // filter out Draft API products - only include Published ones\n const publishedProducts = apiProducts.filter(product => {\n const publishStatus = product.spec.publishStatus || 'Draft'; // default to Draft if not specified\n return publishStatus === 'Published';\n });\n console.log(`apiproduct provider: filtered to ${publishedProducts.length} published apiproducts (${apiProducts.length - publishedProducts.length} drafts excluded)`);\n\n // transform apiproducts to backstage api entities\n const entities = publishedProducts\n .map(product => this.transformToEntity(product))\n .filter((entity): entity is ApiEntity => entity !== null);\n console.log(`apiproduct provider: transformed ${entities.length} entities`);\n\n // submit entities to catalog\n console.log('apiproduct provider: submitting entities to catalog');\n await this.connection.applyMutation({\n type: 'full',\n entities: entities.map(entity => ({\n entity,\n locationKey: `kuadrant-apiproduct:${entity.metadata.namespace}/${entity.metadata.name}`,\n })),\n });\n\n console.log(`apiproduct provider: synced ${entities.length} api products`);\n } catch (error) {\n console.error('error refreshing apiproduct entities:', error);\n }\n }\n\n private transformToEntity(product: APIProduct): ApiEntity | null {\n const namespace = product.metadata.namespace || 'default';\n const name = product.metadata.name;\n const displayName = product.spec.displayName || name;\n const description = product.spec.description || `api product: ${displayName}`;\n\n // determine lifecycle from labels or default to production\n const lifecycle = product.metadata.labels?.lifecycle || 'production';\n\n // owner must be set via backstage ownership annotation\n // if missing, skip this apiproduct (created outside backstage or invalid)\n const owner = product.metadata.annotations?.['backstage.io/owner'];\n if (!owner) {\n console.warn(`apiproduct ${namespace}/${name} has no backstage.io/owner annotation, skipping catalog sync`);\n return null;\n }\n\n // build tags from product tags\n const tags = product.spec.tags || [];\n\n // OpenAPI spec URL\n const definition = product.status?.openapi?.raw ? `${product.status.openapi.raw}`\n : `# no openapi spec configured\n openapi: 3.0.0\n info:\n title: ${displayName}\n version: ${product.spec.version || '1.0.0'}\n description: ${description}\n `;\n\n // create entity with proper backstage structure\n const entity: ApiEntity = {\n apiVersion: 'backstage.io/v1alpha1',\n kind: 'API',\n metadata: {\n name: `${name}`,\n namespace: 'default',\n title: displayName,\n description,\n annotations: {\n 'backstage.io/managed-by-location': `kuadrant:${namespace}/${name}`,\n 'backstage.io/managed-by-origin-location': `kuadrant:${namespace}/${name}`,\n 'backstage.io/orphan-strategy': 'keep',\n 'kuadrant.io/namespace': namespace,\n 'kuadrant.io/apiproduct': name,\n // add httproute annotation if we can infer it (usually same as apiproduct name without -api suffix)\n 'kuadrant.io/httproute': name.endsWith('-api') ? name.slice(0, -4) : name,\n ...(product.spec.documentation?.openAPISpec && {\n 'kuadrant.io/openapi-spec-url': product.spec.documentation.openAPISpec,\n }),\n ...(product.spec.documentation?.docsURL && {\n 'kuadrant.io/docs-url': product.spec.documentation.docsURL,\n }),\n ...(product.spec.documentation?.gitRepository && {\n 'backstage.io/source-location': `url:${product.spec.documentation.gitRepository}`,\n }),\n ...(product.spec.documentation?.techdocsRef && {\n 'backstage.io/techdocs-ref': product.spec.documentation.techdocsRef,\n }),\n ...(product.spec.contact?.email && {\n 'kuadrant.io/contact-email': product.spec.contact.email,\n }),\n ...(product.spec.contact?.slack && {\n 'kuadrant.io/contact-slack': product.spec.contact.slack,\n }),\n },\n tags: [...tags, 'kuadrant', 'apiproduct'],\n labels: {\n 'kuadrant.io/synced': 'true',\n ...(product.metadata.labels || {}),\n },\n },\n spec: {\n type: 'openapi',\n lifecycle,\n owner,\n definition: definition,\n },\n };\n\n return entity;\n }\n}\n"],"names":["KuadrantK8sClient"],"mappings":"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"}
@@ -62,7 +62,7 @@ async function createRouter({
62
62
  throw new errors.NotAllowedError("unauthorised");
63
63
  }
64
64
  const { userEntityRef } = await getUserIdentity(req, httpAuth, userInfo);
65
- const data = await k8sClient$1.listCustomResources("extensions.kuadrant.io", "v1alpha1", "apiproducts");
65
+ const data = await k8sClient$1.listCustomResources("devportal.kuadrant.io", "v1alpha1", "apiproducts");
66
66
  const readAllDecision = await permissions$1.authorize(
67
67
  [{ permission: permissions.kuadrantApiProductReadAllPermission }],
68
68
  { credentials }
@@ -109,14 +109,14 @@ async function createRouter({
109
109
  throw new errors.NotAllowedError("unauthorised");
110
110
  }
111
111
  const { userEntityRef } = await getUserIdentity(req, httpAuth, userInfo);
112
- const data = await k8sClient$1.getCustomResource("extensions.kuadrant.io", "v1alpha1", namespace, "apiproducts", name);
112
+ const data = await k8sClient$1.getCustomResource("devportal.kuadrant.io", "v1alpha1", namespace, "apiproducts", name);
113
113
  const owner = data.metadata?.annotations?.["backstage.io/owner"];
114
114
  if (owner !== userEntityRef) {
115
115
  throw new errors.NotAllowedError("you can only read your own api products");
116
116
  }
117
117
  res.json(data);
118
118
  } else {
119
- const data = await k8sClient$1.getCustomResource("extensions.kuadrant.io", "v1alpha1", namespace, "apiproducts", name);
119
+ const data = await k8sClient$1.getCustomResource("devportal.kuadrant.io", "v1alpha1", namespace, "apiproducts", name);
120
120
  res.json(data);
121
121
  }
122
122
  } catch (error) {
@@ -177,7 +177,7 @@ async function createRouter({
177
177
  console.warn("failed to populate plans from planpolicy:", error);
178
178
  }
179
179
  const created = await k8sClient$1.createCustomResource(
180
- "extensions.kuadrant.io",
180
+ "devportal.kuadrant.io",
181
181
  "v1alpha1",
182
182
  namespace,
183
183
  "apiproducts",
@@ -217,14 +217,14 @@ async function createRouter({
217
217
  throw new errors.NotAllowedError("unauthorised");
218
218
  }
219
219
  const { userEntityRef } = await getUserIdentity(req, httpAuth, userInfo);
220
- const existing = await k8sClient$1.getCustomResource("extensions.kuadrant.io", "v1alpha1", namespace, "apiproducts", name);
220
+ const existing = await k8sClient$1.getCustomResource("devportal.kuadrant.io", "v1alpha1", namespace, "apiproducts", name);
221
221
  const owner = existing.metadata?.annotations?.["backstage.io/owner"];
222
222
  if (owner !== userEntityRef) {
223
223
  throw new errors.NotAllowedError("you can only delete your own api products");
224
224
  }
225
225
  }
226
226
  await k8sClient$1.deleteCustomResource(
227
- "extensions.kuadrant.io",
227
+ "devportal.kuadrant.io",
228
228
  "v1alpha1",
229
229
  namespace,
230
230
  "apiproducts",
@@ -308,7 +308,7 @@ async function createRouter({
308
308
  throw new errors.NotAllowedError("unauthorised");
309
309
  }
310
310
  const { userEntityRef } = await getUserIdentity(req, httpAuth, userInfo);
311
- const existing = await k8sClient$1.getCustomResource("extensions.kuadrant.io", "v1alpha1", namespace, "apiproducts", name);
311
+ const existing = await k8sClient$1.getCustomResource("devportal.kuadrant.io", "v1alpha1", namespace, "apiproducts", name);
312
312
  const owner = existing.metadata?.annotations?.["backstage.io/owner"];
313
313
  if (owner !== userEntityRef) {
314
314
  throw new errors.NotAllowedError("you can only update your own api products");
@@ -318,7 +318,7 @@ async function createRouter({
318
318
  delete req.body.metadata.annotations["backstage.io/owner"];
319
319
  }
320
320
  const updated = await k8sClient$1.patchCustomResource(
321
- "extensions.kuadrant.io",
321
+ "devportal.kuadrant.io",
322
322
  "v1alpha1",
323
323
  namespace,
324
324
  "apiproducts",
@@ -402,8 +402,10 @@ async function createRouter({
402
402
  }
403
403
  });
404
404
  const requestSchema = zod.z.object({
405
- apiName: zod.z.string(),
406
- apiNamespace: zod.z.string(),
405
+ apiProductName: zod.z.string(),
406
+ // name of the APIProduct
407
+ namespace: zod.z.string(),
408
+ // namespace where both APIProduct and APIKey live
407
409
  planTier: zod.z.string(),
408
410
  useCase: zod.z.string().optional(),
409
411
  userEmail: zod.z.string().optional()
@@ -415,9 +417,9 @@ async function createRouter({
415
417
  }
416
418
  try {
417
419
  const credentials = await httpAuth.credentials(req);
418
- const { apiName, apiNamespace, planTier, useCase, userEmail } = parsed.data;
420
+ const { apiProductName, namespace, planTier, useCase, userEmail } = parsed.data;
419
421
  const { userEntityRef } = await getUserIdentity(req, httpAuth, userInfo);
420
- const resourceRef = `apiproduct:${apiNamespace}/${apiName}`;
422
+ const resourceRef = `apiproduct:${namespace}/${apiProductName}`;
421
423
  const decision = await permissions$1.authorize(
422
424
  [{
423
425
  permission: permissions.kuadrantApiKeyRequestCreatePermission,
@@ -426,60 +428,59 @@ async function createRouter({
426
428
  { credentials }
427
429
  );
428
430
  if (decision[0].result !== pluginPermissionCommon.AuthorizeResult.ALLOW) {
429
- throw new errors.NotAllowedError(`not authorised to request access to ${apiName}`);
431
+ throw new errors.NotAllowedError(`not authorised to request access to ${apiProductName}`);
430
432
  }
431
- const timestamp = (/* @__PURE__ */ new Date()).toISOString();
432
433
  const randomSuffix = crypto.randomBytes(4).toString("hex");
433
434
  const userName = extractNameFromEntityRef(userEntityRef);
434
- const requestName = `${userName}-${apiName}-${randomSuffix}`.toLowerCase().replace(/[^a-z0-9-]/g, "-");
435
+ const requestName = `${userName}-${apiProductName}-${randomSuffix}`.toLowerCase().replace(/[^a-z0-9-]/g, "-");
435
436
  const requestedBy = { userId: userEntityRef };
436
437
  if (userEmail) {
437
438
  requestedBy.email = userEmail;
438
439
  }
439
440
  const request = {
440
- apiVersion: "extensions.kuadrant.io/v1alpha1",
441
- kind: "APIKeyRequest",
441
+ apiVersion: "devportal.kuadrant.io/v1alpha1",
442
+ kind: "APIKey",
442
443
  metadata: {
443
444
  name: requestName,
444
- namespace: apiNamespace
445
+ namespace
445
446
  },
446
447
  spec: {
447
- apiName,
448
- apiNamespace,
448
+ apiProductRef: {
449
+ name: apiProductName
450
+ },
449
451
  planTier,
450
452
  useCase: useCase || "",
451
- requestedBy,
452
- requestedAt: timestamp
453
+ requestedBy
453
454
  }
454
455
  };
455
456
  const created = await k8sClient$1.createCustomResource(
456
- "extensions.kuadrant.io",
457
+ "devportal.kuadrant.io",
457
458
  "v1alpha1",
458
- apiNamespace,
459
- "apikeyrequests",
459
+ namespace,
460
+ "apikeys",
460
461
  request
461
462
  );
462
463
  try {
463
464
  const apiProduct = await k8sClient$1.getCustomResource(
464
- "extensions.kuadrant.io",
465
+ "devportal.kuadrant.io",
465
466
  "v1alpha1",
466
- apiNamespace,
467
+ namespace,
467
468
  "apiproducts",
468
- apiName
469
+ apiProductName
469
470
  );
470
471
  if (apiProduct.spec?.approvalMode === "automatic") {
471
472
  const apiKey = generateApiKey();
472
- const timestamp2 = Date.now();
473
+ const timestamp = Date.now();
473
474
  const userName2 = extractNameFromEntityRef(userEntityRef);
474
- const secretName = `${userName2}-${apiName}-${timestamp2}`.toLowerCase().replace(/[^a-z0-9-]/g, "-");
475
+ const secretName = `${userName2}-${apiProductName}-${timestamp}`.toLowerCase().replace(/[^a-z0-9-]/g, "-");
475
476
  const secret = {
476
477
  apiVersion: "v1",
477
478
  kind: "Secret",
478
479
  metadata: {
479
480
  name: secretName,
480
- namespace: apiNamespace,
481
+ namespace,
481
482
  labels: {
482
- app: apiName
483
+ app: apiProductName
483
484
  },
484
485
  annotations: {
485
486
  "secret.kuadrant.io/plan-id": planTier,
@@ -491,20 +492,20 @@ async function createRouter({
491
492
  },
492
493
  type: "Opaque"
493
494
  };
494
- await k8sClient$1.createSecret(apiNamespace, secret);
495
+ await k8sClient$1.createSecret(namespace, secret);
495
496
  let planLimits = null;
496
497
  const plan = apiProduct.spec?.plans?.find((p) => p.tier === planTier);
497
498
  if (plan) {
498
499
  planLimits = plan.limits;
499
500
  }
500
- let apiHostname = `${apiName}.apps.example.com`;
501
+ let apiHostname = `${apiProductName}.apps.example.com`;
501
502
  try {
502
503
  const httproute = await k8sClient$1.getCustomResource(
503
504
  "gateway.networking.k8s.io",
504
505
  "v1",
505
- apiNamespace,
506
+ namespace,
506
507
  "httproutes",
507
- apiName
508
+ apiProductName
508
509
  );
509
510
  if (httproute.spec?.hostnames && httproute.spec.hostnames.length > 0) {
510
511
  apiHostname = httproute.spec.hostnames[0];
@@ -520,14 +521,14 @@ async function createRouter({
520
521
  apiKey,
521
522
  apiHostname,
522
523
  apiBasePath: "/api/v1",
523
- apiDescription: `${apiName} api`,
524
+ apiDescription: `${apiProductName} api`,
524
525
  planLimits
525
526
  };
526
527
  await k8sClient$1.patchCustomResourceStatus(
527
- "extensions.kuadrant.io",
528
+ "devportal.kuadrant.io",
528
529
  "v1alpha1",
529
- apiNamespace,
530
- "apikeyrequests",
530
+ namespace,
531
+ "apikeys",
531
532
  requestName,
532
533
  status
533
534
  );
@@ -566,14 +567,14 @@ async function createRouter({
566
567
  const namespace = req.query.namespace;
567
568
  let data;
568
569
  if (namespace) {
569
- data = await k8sClient$1.listCustomResources("extensions.kuadrant.io", "v1alpha1", "apikeyrequests", namespace);
570
+ data = await k8sClient$1.listCustomResources("devportal.kuadrant.io", "v1alpha1", "aPIKeys", namespace);
570
571
  } else {
571
- data = await k8sClient$1.listCustomResources("extensions.kuadrant.io", "v1alpha1", "apikeyrequests");
572
+ data = await k8sClient$1.listCustomResources("devportal.kuadrant.io", "v1alpha1", "aPIKeys");
572
573
  }
573
574
  let filteredItems = data.items || [];
574
575
  if (!canReadAll) {
575
576
  const { userEntityRef } = await getUserIdentity(req, httpAuth, userInfo);
576
- const apiproducts = await k8sClient$1.listCustomResources("extensions.kuadrant.io", "v1alpha1", "apiproducts");
577
+ const apiproducts = await k8sClient$1.listCustomResources("devportal.kuadrant.io", "v1alpha1", "apiproducts");
577
578
  const ownedApiProducts = (apiproducts.items || []).filter((product) => {
578
579
  const owner = product.metadata?.annotations?.["backstage.io/owner"];
579
580
  return owner === userEntityRef;
@@ -612,9 +613,9 @@ async function createRouter({
612
613
  const namespace = req.query.namespace;
613
614
  let data;
614
615
  if (namespace) {
615
- data = await k8sClient$1.listCustomResources("extensions.kuadrant.io", "v1alpha1", "apikeyrequests", namespace);
616
+ data = await k8sClient$1.listCustomResources("devportal.kuadrant.io", "v1alpha1", "apikeys", namespace);
616
617
  } else {
617
- data = await k8sClient$1.listCustomResources("extensions.kuadrant.io", "v1alpha1", "apikeyrequests");
618
+ data = await k8sClient$1.listCustomResources("devportal.kuadrant.io", "v1alpha1", "apikeys");
618
619
  }
619
620
  const filteredItems = (data.items || []).filter(
620
621
  (req2) => req2.spec?.requestedBy?.userId === userEntityRef
@@ -644,19 +645,23 @@ async function createRouter({
644
645
  const { comment } = parsed.data;
645
646
  const reviewedBy = userEntityRef;
646
647
  const request = await k8sClient$1.getCustomResource(
647
- "extensions.kuadrant.io",
648
+ "devportal.kuadrant.io",
648
649
  "v1alpha1",
649
650
  namespace,
650
- "apikeyrequests",
651
+ "apikeys",
651
652
  name
652
653
  );
653
654
  const spec = request.spec;
655
+ const apiProductName = spec.apiProductRef?.name;
656
+ if (!apiProductName) {
657
+ throw new errors.InputError("apiProductRef.name is required in APIKey spec");
658
+ }
654
659
  const apiProduct = await k8sClient$1.getCustomResource(
655
- "extensions.kuadrant.io",
660
+ "devportal.kuadrant.io",
656
661
  "v1alpha1",
657
- spec.apiNamespace,
662
+ namespace,
658
663
  "apiproducts",
659
- spec.apiName
664
+ apiProductName
660
665
  );
661
666
  const owner = apiProduct.metadata?.annotations?.["backstage.io/owner"];
662
667
  const updateAllDecision = await permissions$1.authorize(
@@ -678,15 +683,15 @@ async function createRouter({
678
683
  const apiKey = generateApiKey();
679
684
  const timestamp = Date.now();
680
685
  const userName = extractNameFromEntityRef(spec.requestedBy.userId);
681
- const secretName = `${userName}-${spec.apiName}-${timestamp}`.toLowerCase().replace(/[^a-z0-9-]/g, "-");
686
+ const secretName = `${userName}-${apiProductName}-${timestamp}`.toLowerCase().replace(/[^a-z0-9-]/g, "-");
682
687
  const secret = {
683
688
  apiVersion: "v1",
684
689
  kind: "Secret",
685
690
  metadata: {
686
691
  name: secretName,
687
- namespace: spec.apiNamespace,
692
+ namespace,
688
693
  labels: {
689
- app: spec.apiName
694
+ app: apiProductName
690
695
  },
691
696
  annotations: {
692
697
  "secret.kuadrant.io/plan-id": spec.planTier,
@@ -698,12 +703,12 @@ async function createRouter({
698
703
  },
699
704
  type: "Opaque"
700
705
  };
701
- await k8sClient$1.createSecret(spec.apiNamespace, secret);
706
+ await k8sClient$1.createSecret(namespace, secret);
702
707
  let planLimits = null;
703
708
  try {
704
- const products = await k8sClient$1.listCustomResources("extensions.kuadrant.io", "v1alpha1", "apiproducts");
709
+ const products = await k8sClient$1.listCustomResources("devportal.kuadrant.io", "v1alpha1", "apiproducts");
705
710
  const product = (products.items || []).find(
706
- (p) => p.metadata.name.includes(spec.apiName) || p.spec?.displayName?.toLowerCase().includes(spec.apiName.toLowerCase())
711
+ (p) => p.metadata.name.includes(apiProductName) || p.spec?.displayName?.toLowerCase().includes(apiProductName.toLowerCase())
707
712
  );
708
713
  if (product) {
709
714
  const plan = product.spec?.plans?.find((p) => p.tier === spec.planTier);
@@ -719,9 +724,9 @@ async function createRouter({
719
724
  const policy = await k8sClient$1.getCustomResource(
720
725
  "extensions.kuadrant.io",
721
726
  "v1alpha1",
722
- spec.apiNamespace,
727
+ namespace,
723
728
  "planpolicies",
724
- `${spec.apiName}-plan`
729
+ `${apiProductName}-plan`
725
730
  );
726
731
  const plan = policy.spec?.plans?.find((p) => p.tier === spec.planTier);
727
732
  if (plan) {
@@ -731,14 +736,14 @@ async function createRouter({
731
736
  console.warn("could not fetch planpolicy for plan limits:", e);
732
737
  }
733
738
  }
734
- let apiHostname = `${spec.apiName}.apps.example.com`;
739
+ let apiHostname = `${apiProductName}.apps.example.com`;
735
740
  try {
736
741
  const httproute = await k8sClient$1.getCustomResource(
737
742
  "gateway.networking.k8s.io",
738
743
  "v1",
739
- spec.apiNamespace,
744
+ namespace,
740
745
  "httproutes",
741
- spec.apiName
746
+ apiProductName
742
747
  );
743
748
  if (httproute.spec?.hostnames && httproute.spec.hostnames.length > 0) {
744
749
  apiHostname = httproute.spec.hostnames[0];
@@ -754,14 +759,14 @@ async function createRouter({
754
759
  apiKey,
755
760
  apiHostname,
756
761
  apiBasePath: "/api/v1",
757
- apiDescription: `${spec.apiName} api`,
762
+ apiDescription: `${apiProductName} api`,
758
763
  planLimits
759
764
  };
760
765
  await k8sClient$1.patchCustomResourceStatus(
761
- "extensions.kuadrant.io",
766
+ "devportal.kuadrant.io",
762
767
  "v1alpha1",
763
768
  namespace,
764
- "apikeyrequests",
769
+ "apikeys",
765
770
  name,
766
771
  status
767
772
  );
@@ -787,19 +792,23 @@ async function createRouter({
787
792
  const { comment } = parsed.data;
788
793
  const reviewedBy = userEntityRef;
789
794
  const request = await k8sClient$1.getCustomResource(
790
- "extensions.kuadrant.io",
795
+ "devportal.kuadrant.io",
791
796
  "v1alpha1",
792
797
  namespace,
793
- "apikeyrequests",
798
+ "apikeys",
794
799
  name
795
800
  );
796
801
  const spec = request.spec;
802
+ const apiProductName = spec.apiProductRef?.name;
803
+ if (!apiProductName) {
804
+ throw new errors.InputError("apiProductRef.name is required in APIKey spec");
805
+ }
797
806
  const apiProduct = await k8sClient$1.getCustomResource(
798
- "extensions.kuadrant.io",
807
+ "devportal.kuadrant.io",
799
808
  "v1alpha1",
800
- spec.apiNamespace,
809
+ namespace,
801
810
  "apiproducts",
802
- spec.apiName
811
+ apiProductName
803
812
  );
804
813
  const owner = apiProduct.metadata?.annotations?.["backstage.io/owner"];
805
814
  const updateAllDecision = await permissions$1.authorize(
@@ -825,10 +834,10 @@ async function createRouter({
825
834
  reason: comment || "rejected"
826
835
  };
827
836
  await k8sClient$1.patchCustomResourceStatus(
828
- "extensions.kuadrant.io",
837
+ "devportal.kuadrant.io",
829
838
  "v1alpha1",
830
839
  namespace,
831
- "apikeyrequests",
840
+ "apikeys",
832
841
  name,
833
842
  status
834
843
  );
@@ -870,15 +879,15 @@ async function createRouter({
870
879
  for (const reqRef of requests) {
871
880
  try {
872
881
  const request = await k8sClient$1.getCustomResource(
873
- "extensions.kuadrant.io",
882
+ "devportal.kuadrant.io",
874
883
  "v1alpha1",
875
884
  reqRef.namespace,
876
- "apikeyrequests",
885
+ "apikeys",
877
886
  reqRef.name
878
887
  );
879
888
  const spec = request.spec;
880
889
  const apiProduct = await k8sClient$1.getCustomResource(
881
- "extensions.kuadrant.io",
890
+ "devportal.kuadrant.io",
882
891
  "v1alpha1",
883
892
  spec.apiNamespace,
884
893
  "apiproducts",
@@ -927,7 +936,7 @@ async function createRouter({
927
936
  await k8sClient$1.createSecret(spec.apiNamespace, secret);
928
937
  let planLimits = null;
929
938
  try {
930
- const products = await k8sClient$1.listCustomResources("extensions.kuadrant.io", "v1alpha1", "apiproducts");
939
+ const products = await k8sClient$1.listCustomResources("devportal.kuadrant.io", "v1alpha1", "apiproducts");
931
940
  const product = (products.items || []).find(
932
941
  (p) => p.metadata.name.includes(spec.apiName) || p.spec?.displayName?.toLowerCase().includes(spec.apiName.toLowerCase())
933
942
  );
@@ -943,7 +952,7 @@ async function createRouter({
943
952
  if (!planLimits) {
944
953
  try {
945
954
  const policy = await k8sClient$1.getCustomResource(
946
- "extensions.kuadrant.io",
955
+ "devportal.kuadrant.io",
947
956
  "v1alpha1",
948
957
  spec.apiNamespace,
949
958
  "planpolicies",
@@ -984,10 +993,10 @@ async function createRouter({
984
993
  planLimits
985
994
  };
986
995
  await k8sClient$1.patchCustomResourceStatus(
987
- "extensions.kuadrant.io",
996
+ "devportal.kuadrant.io",
988
997
  "v1alpha1",
989
998
  reqRef.namespace,
990
- "apikeyrequests",
999
+ "apikeys",
991
1000
  reqRef.name,
992
1001
  status
993
1002
  );
@@ -1033,15 +1042,15 @@ async function createRouter({
1033
1042
  for (const reqRef of requests) {
1034
1043
  try {
1035
1044
  const request = await k8sClient$1.getCustomResource(
1036
- "extensions.kuadrant.io",
1045
+ "devportal.kuadrant.io",
1037
1046
  "v1alpha1",
1038
1047
  reqRef.namespace,
1039
- "apikeyrequests",
1048
+ "apikeys",
1040
1049
  reqRef.name
1041
1050
  );
1042
1051
  const spec = request.spec;
1043
1052
  const apiProduct = await k8sClient$1.getCustomResource(
1044
- "extensions.kuadrant.io",
1053
+ "devportal.kuadrant.io",
1045
1054
  "v1alpha1",
1046
1055
  spec.apiNamespace,
1047
1056
  "apiproducts",
@@ -1071,10 +1080,10 @@ async function createRouter({
1071
1080
  reason: comment || "rejected"
1072
1081
  };
1073
1082
  await k8sClient$1.patchCustomResourceStatus(
1074
- "extensions.kuadrant.io",
1083
+ "devportal.kuadrant.io",
1075
1084
  "v1alpha1",
1076
1085
  reqRef.namespace,
1077
- "apikeyrequests",
1086
+ "apikeys",
1078
1087
  reqRef.name,
1079
1088
  status
1080
1089
  );
@@ -1105,10 +1114,10 @@ async function createRouter({
1105
1114
  const { userEntityRef } = await getUserIdentity(req, httpAuth, userInfo);
1106
1115
  const { namespace, name } = req.params;
1107
1116
  const request = await k8sClient$1.getCustomResource(
1108
- "extensions.kuadrant.io",
1117
+ "devportal.kuadrant.io",
1109
1118
  "v1alpha1",
1110
1119
  namespace,
1111
- "apikeyrequests",
1120
+ "apikeys",
1112
1121
  name
1113
1122
  );
1114
1123
  const requestUserId = request.spec?.requestedBy?.userId;
@@ -1147,10 +1156,10 @@ async function createRouter({
1147
1156
  }
1148
1157
  }
1149
1158
  await k8sClient$1.deleteCustomResource(
1150
- "extensions.kuadrant.io",
1159
+ "devportal.kuadrant.io",
1151
1160
  "v1alpha1",
1152
1161
  namespace,
1153
- "apikeyrequests",
1162
+ "apikeys",
1154
1163
  name
1155
1164
  );
1156
1165
  res.status(204).send();
@@ -1179,10 +1188,10 @@ async function createRouter({
1179
1188
  const { userEntityRef } = await getUserIdentity(req, httpAuth, userInfo);
1180
1189
  const { namespace, name } = req.params;
1181
1190
  const existing = await k8sClient$1.getCustomResource(
1182
- "extensions.kuadrant.io",
1191
+ "devportal.kuadrant.io",
1183
1192
  "v1alpha1",
1184
1193
  namespace,
1185
- "apikeyrequests",
1194
+ "apikeys",
1186
1195
  name
1187
1196
  );
1188
1197
  const requestUserId = existing.spec?.requestedBy?.userId;
@@ -1207,10 +1216,10 @@ async function createRouter({
1207
1216
  }
1208
1217
  }
1209
1218
  const updated = await k8sClient$1.patchCustomResource(
1210
- "extensions.kuadrant.io",
1219
+ "devportal.kuadrant.io",
1211
1220
  "v1alpha1",
1212
1221
  namespace,
1213
- "apikeyrequests",
1222
+ "apikeys",
1214
1223
  name,
1215
1224
  parsed.data
1216
1225
  );
@@ -1 +1 @@
1
- {"version":3,"file":"router.cjs.js","sources":["../src/router.ts"],"sourcesContent":["import { HttpAuthService, RootConfigService, UserInfoService, PermissionsService } from '@backstage/backend-plugin-api';\nimport { InputError, NotAllowedError } from '@backstage/errors';\nimport { AuthorizeResult } from '@backstage/plugin-permission-common';\nimport { createPermissionIntegrationRouter } from '@backstage/plugin-permission-node';\nimport { z } from 'zod';\nimport express from 'express';\nimport Router from 'express-promise-router';\nimport cors from 'cors';\nimport { randomBytes } from 'crypto';\nimport { KuadrantK8sClient } from './k8s-client';\nimport { getAPIProductEntityProvider } from './module';\nimport {\n kuadrantPermissions,\n kuadrantPlanPolicyListPermission,\n kuadrantPlanPolicyReadPermission,\n kuadrantApiProductListPermission,\n kuadrantApiProductReadOwnPermission,\n kuadrantApiProductReadAllPermission,\n kuadrantApiProductCreatePermission,\n kuadrantApiProductUpdateOwnPermission,\n kuadrantApiProductUpdateAllPermission,\n kuadrantApiProductDeleteOwnPermission,\n kuadrantApiProductDeleteAllPermission,\n kuadrantApiKeyRequestCreatePermission,\n kuadrantApiKeyRequestReadOwnPermission,\n kuadrantApiKeyRequestReadAllPermission,\n kuadrantApiKeyRequestUpdateOwnPermission,\n kuadrantApiKeyRequestUpdateAllPermission,\n kuadrantApiKeyRequestDeleteOwnPermission,\n kuadrantApiKeyRequestDeleteAllPermission,\n} from './permissions';\n\nfunction generateApiKey(): string {\n return randomBytes(32).toString('hex');\n}\n\n/**\n * Extract a kubernetes-safe name from entity ref\n * e.g., \"user:default/alice\" -> \"alice\"\n * e.g., \"group:platform/api-owners\" -> \"api-owners\"\n */\nfunction extractNameFromEntityRef(entityRef: string): string {\n const parts = entityRef.split('/');\n return parts[parts.length - 1];\n}\n\nasync function getUserIdentity(req: express.Request, httpAuth: HttpAuthService, userInfo: UserInfoService): Promise<{\n userEntityRef: string;\n groups: string[];\n}> {\n const credentials = await httpAuth.credentials(req);\n\n if (!credentials || !credentials.principal) {\n throw new NotAllowedError('authentication required');\n }\n\n // get user info from credentials\n const info = await userInfo.getUserInfo(credentials);\n const groups = info.ownershipEntityRefs || [];\n\n console.log(`user identity resolved: userEntityRef=${info.userEntityRef}, groups=${groups.join(',')}`);\n return {\n userEntityRef: info.userEntityRef,\n groups\n };\n}\n\nexport async function createRouter({\n httpAuth,\n userInfo,\n config,\n permissions,\n}: {\n httpAuth: HttpAuthService;\n userInfo: UserInfoService;\n config: RootConfigService;\n permissions: PermissionsService;\n}): Promise<express.Router> {\n const router = Router();\n\n // enable cors for dev mode (allows frontend on :3000 to call backend on :7007)\n router.use(cors({\n origin: 'http://localhost:3000',\n credentials: true,\n }));\n\n router.use(express.json());\n\n const k8sClient = new KuadrantK8sClient(config);\n\n // apiproduct endpoints\n router.get('/apiproducts', async (req, res) => {\n try {\n const credentials = await httpAuth.credentials(req);\n\n const listDecision = await permissions.authorize(\n [{ permission: kuadrantApiProductListPermission }],\n { credentials }\n );\n\n if (listDecision[0].result !== AuthorizeResult.ALLOW) {\n throw new NotAllowedError('unauthorised');\n }\n\n const { userEntityRef } = await getUserIdentity(req, httpAuth, userInfo);\n const data = await k8sClient.listCustomResources('extensions.kuadrant.io', 'v1alpha1', 'apiproducts');\n\n // check if user has read all permission\n const readAllDecision = await permissions.authorize(\n [{ permission: kuadrantApiProductReadAllPermission }],\n { credentials }\n );\n\n if (readAllDecision[0].result === AuthorizeResult.ALLOW) {\n // admin - return all apiproducts\n res.json(data);\n } else {\n // owner - check read own permission and filter\n const readOwnDecision = await permissions.authorize(\n [{ permission: kuadrantApiProductReadOwnPermission }],\n { credentials }\n );\n\n if (readOwnDecision[0].result !== AuthorizeResult.ALLOW) {\n throw new NotAllowedError('unauthorised');\n }\n\n // filter to only owned apiproducts\n const ownedItems = (data.items || []).filter((item: any) => {\n const owner = item.metadata?.annotations?.['backstage.io/owner'];\n return owner === userEntityRef;\n });\n\n res.json({ ...data, items: ownedItems });\n }\n } catch (error) {\n console.error('error fetching apiproducts:', error);\n if (error instanceof NotAllowedError) {\n res.status(403).json({ error: error.message });\n } else {\n res.status(500).json({ error: 'failed to fetch apiproducts' });\n }\n }\n });\n\n router.get('/apiproducts/:namespace/:name', async (req, res) => {\n try {\n const credentials = await httpAuth.credentials(req);\n const { namespace, name } = req.params;\n\n // try read all permission first (admin)\n const readAllDecision = await permissions.authorize(\n [{ permission: kuadrantApiProductReadAllPermission }],\n { credentials }\n );\n\n if (readAllDecision[0].result !== AuthorizeResult.ALLOW) {\n // fallback to read own permission\n const readOwnDecision = await permissions.authorize(\n [{ permission: kuadrantApiProductReadOwnPermission }],\n { credentials }\n );\n\n if (readOwnDecision[0].result !== AuthorizeResult.ALLOW) {\n throw new NotAllowedError('unauthorised');\n }\n\n // verify ownership\n const { userEntityRef } = await getUserIdentity(req, httpAuth, userInfo);\n const data = await k8sClient.getCustomResource('extensions.kuadrant.io', 'v1alpha1', namespace, 'apiproducts', name);\n const owner = data.metadata?.annotations?.['backstage.io/owner'];\n // owner is already in entity ref format\n\n if (owner !== userEntityRef) {\n throw new NotAllowedError('you can only read your own api products');\n }\n\n res.json(data);\n } else {\n // admin - read any apiproduct\n const data = await k8sClient.getCustomResource('extensions.kuadrant.io', 'v1alpha1', namespace, 'apiproducts', name);\n res.json(data);\n }\n } catch (error) {\n console.error('error fetching apiproduct:', error);\n if (error instanceof NotAllowedError) {\n res.status(403).json({ error: error.message });\n } else {\n res.status(500).json({ error: 'failed to fetch apiproduct' });\n }\n }\n });\n\n router.post('/apiproducts', async (req, res) => {\n try {\n const credentials = await httpAuth.credentials(req);\n\n const decision = await permissions.authorize(\n [{ permission: kuadrantApiProductCreatePermission }],\n { credentials }\n );\n\n if (decision[0].result !== AuthorizeResult.ALLOW) {\n throw new NotAllowedError('unauthorised');\n }\n\n const { userEntityRef } = await getUserIdentity(req, httpAuth, userInfo);\n const apiProduct = req.body;\n const targetRef = apiProduct.spec?.targetRef;\n\n if (!targetRef?.name || !targetRef?.kind || !targetRef?.namespace) {\n throw new InputError('targetRef with name, kind, and namespace is required');\n }\n\n // derive namespace from httproute - apiproduct lives in same namespace as httproute\n const namespace = targetRef.namespace;\n apiProduct.metadata.namespace = namespace;\n\n // set ownership annotation (backstage-specific metadata)\n // note: creationTimestamp is automatically set by kubernetes api server\n if (!apiProduct.metadata.annotations) {\n apiProduct.metadata.annotations = {};\n }\n apiProduct.metadata.annotations['backstage.io/owner'] = userEntityRef;\n\n // temporary: populate plans from planpolicy until controller implements this\n // look up httproute and find planpolicy targeting it\n const httpRouteNamespace = namespace;\n const httpRouteName = targetRef.name;\n\n try {\n // list all planpolicies in the httproute's namespace\n const planPoliciesResponse = await k8sClient.listCustomResources(\n 'extensions.kuadrant.io',\n 'v1alpha1',\n 'planpolicies',\n httpRouteNamespace\n );\n\n // find planpolicy targeting this httproute\n const planPolicy = (planPoliciesResponse.items || []).find((pp: any) => {\n const ref = pp.spec?.targetRef;\n return ref?.kind === 'HTTPRoute' &&\n ref?.name === httpRouteName &&\n (!ref?.namespace || ref?.namespace === httpRouteNamespace);\n });\n\n if (planPolicy && planPolicy.spec?.plans) {\n // copy plans from planpolicy to apiproduct spec\n apiProduct.spec.plans = planPolicy.spec.plans.map((plan: any) => ({\n tier: plan.tier,\n description: plan.description,\n limits: plan.limits\n }));\n console.log(`copied ${apiProduct.spec.plans.length} plans from planpolicy ${planPolicy.metadata.name}`);\n } else {\n console.log(`no planpolicy found for httproute ${httpRouteNamespace}/${httpRouteName}`);\n }\n } catch (error) {\n console.warn('failed to populate plans from planpolicy:', error);\n // continue without plans rather than failing the creation\n }\n\n const created = await k8sClient.createCustomResource(\n 'extensions.kuadrant.io',\n 'v1alpha1',\n namespace,\n 'apiproducts',\n apiProduct,\n );\n\n // trigger immediate catalog sync\n const provider = getAPIProductEntityProvider();\n if (provider) {\n await provider.refresh();\n }\n\n res.status(201).json(created);\n } catch (error) {\n console.error('error creating apiproduct:', error);\n const errorMessage = error instanceof Error ? error.message : String(error);\n\n if (error instanceof NotAllowedError) {\n res.status(403).json({ error: error.message });\n } else if (error instanceof InputError) {\n res.status(400).json({ error: error.message });\n } else {\n // pass the detailed error message to the frontend\n res.status(500).json({ error: errorMessage });\n }\n }\n });\n\n router.delete('/apiproducts/:namespace/:name', async (req, res) => {\n try {\n const credentials = await httpAuth.credentials(req);\n const { namespace, name } = req.params;\n\n // try delete all permission first (admin)\n const deleteAllDecision = await permissions.authorize(\n [{ permission: kuadrantApiProductDeleteAllPermission }],\n { credentials }\n );\n\n if (deleteAllDecision[0].result !== AuthorizeResult.ALLOW) {\n // fallback to delete own permission\n const deleteOwnDecision = await permissions.authorize(\n [{ permission: kuadrantApiProductDeleteOwnPermission }],\n { credentials }\n );\n\n if (deleteOwnDecision[0].result !== AuthorizeResult.ALLOW) {\n throw new NotAllowedError('unauthorised');\n }\n\n // verify ownership before deleting\n const { userEntityRef } = await getUserIdentity(req, httpAuth, userInfo);\n const existing = await k8sClient.getCustomResource('extensions.kuadrant.io', 'v1alpha1', namespace, 'apiproducts', name);\n const owner = existing.metadata?.annotations?.['backstage.io/owner'];\n // owner is already in entity ref format\n\n if (owner !== userEntityRef) {\n throw new NotAllowedError('you can only delete your own api products');\n }\n }\n\n await k8sClient.deleteCustomResource(\n 'extensions.kuadrant.io',\n 'v1alpha1',\n namespace,\n 'apiproducts',\n name\n );\n\n // trigger immediate catalog sync\n const provider = getAPIProductEntityProvider();\n if (provider) {\n await provider.refresh();\n }\n\n res.status(204).send();\n } catch (error) {\n console.error('error deleting apiproduct:', error);\n if (error instanceof NotAllowedError) {\n res.status(403).json({ error: error.message });\n } else {\n res.status(500).json({ error: 'failed to delete apiproduct' });\n }\n }\n });\n\n // httproute endpoints\n router.get('/httproutes', async (req, res) => {\n try {\n const credentials = await httpAuth.credentials(req);\n\n const decision = await permissions.authorize(\n [{ permission: kuadrantApiProductListPermission }],\n { credentials }\n );\n\n if (decision[0].result !== AuthorizeResult.ALLOW) {\n throw new NotAllowedError('unauthorised');\n }\n\n const data = await k8sClient.listCustomResources('gateway.networking.k8s.io', 'v1', 'httproutes');\n\n res.json(data);\n } catch (error) {\n console.error('error fetching httproutes:', error);\n if (error instanceof NotAllowedError) {\n res.status(403).json({ error: error.message });\n } else {\n res.status(500).json({ error: 'failed to fetch httproutes' });\n }\n }\n });\n\n router.patch('/apiproducts/:namespace/:name', async (req, res) => {\n // whitelist allowed fields for patching\n const patchSchema = z.object({\n spec: z.object({\n displayName: z.string().optional(),\n description: z.string().optional(),\n version: z.string().optional(),\n publishStatus: z.enum(['Draft', 'Published']).optional(),\n approvalMode: z.enum(['automatic', 'manual']).optional(),\n tags: z.array(z.string()).optional(),\n contact: z.object({\n email: z.string().optional(),\n team: z.string().optional(),\n slack: z.string().optional(),\n }).partial().optional(),\n documentation: z.object({\n docsURL: z.string().optional(),\n openAPISpec: z.string().optional(),\n }).partial().optional(),\n }).partial(),\n });\n\n const parsed = patchSchema.safeParse(req.body);\n if (!parsed.success) {\n return res.status(400).json({ error: 'invalid patch: ' + parsed.error.toString() });\n }\n\n try {\n const credentials = await httpAuth.credentials(req);\n\n if (!credentials || !credentials.principal) {\n throw new NotAllowedError('authentication required');\n }\n\n const { namespace, name } = req.params;\n\n // try update all permission first (admin)\n const updateAllDecision = await permissions.authorize(\n [{ permission: kuadrantApiProductUpdateAllPermission }],\n { credentials }\n );\n\n if (updateAllDecision[0].result !== AuthorizeResult.ALLOW) {\n // fallback to update own permission\n const updateOwnDecision = await permissions.authorize(\n [{ permission: kuadrantApiProductUpdateOwnPermission }],\n { credentials }\n );\n\n if (updateOwnDecision[0].result !== AuthorizeResult.ALLOW) {\n throw new NotAllowedError('unauthorised');\n }\n\n // verify ownership\n const { userEntityRef } = await getUserIdentity(req, httpAuth, userInfo);\n const existing = await k8sClient.getCustomResource('extensions.kuadrant.io', 'v1alpha1', namespace, 'apiproducts', name);\n const owner = existing.metadata?.annotations?.['backstage.io/owner'];\n // owner is already in entity ref format\n\n if (owner !== userEntityRef) {\n throw new NotAllowedError('you can only update your own api products');\n }\n }\n\n // prevent modification of ownership annotation\n if (req.body.metadata?.annotations) {\n delete req.body.metadata.annotations['backstage.io/owner'];\n }\n\n const updated = await k8sClient.patchCustomResource(\n 'extensions.kuadrant.io',\n 'v1alpha1',\n namespace,\n 'apiproducts',\n name,\n parsed.data,\n );\n\n return res.json(updated);\n } catch (error) {\n console.error('error updating apiproduct:', error);\n const errorMessage = error instanceof Error ? error.message : String(error);\n\n if (error instanceof NotAllowedError) {\n return res.status(403).json({ error: error.message });\n } else if (error instanceof InputError) {\n return res.status(400).json({ error: error.message });\n } else {\n return res.status(500).json({ error: errorMessage });\n }\n }\n });\n\n // planpolicy endpoints\n router.get('/planpolicies', async (req, res) => {\n try {\n const credentials = await httpAuth.credentials(req);\n\n const decision = await permissions.authorize(\n [{ permission: kuadrantPlanPolicyListPermission }],\n { credentials }\n );\n\n if (decision[0].result !== AuthorizeResult.ALLOW) {\n throw new NotAllowedError('unauthorised');\n }\n\n const data = await k8sClient.listCustomResources('extensions.kuadrant.io', 'v1alpha1', 'planpolicies');\n\n // only expose minimal info needed for UI association\n const filtered = {\n items: (data.items || []).map((policy: any) => ({\n metadata: {\n name: policy.metadata.name,\n namespace: policy.metadata.namespace,\n },\n // only expose targetRef to allow UI to match PlanPolicy -> HTTPRoute\n targetRef: policy.spec?.targetRef ? {\n kind: policy.spec.targetRef.kind,\n name: policy.spec.targetRef.name,\n namespace: policy.spec.targetRef.namespace,\n } : undefined,\n // only expose plan tier info, no other spec details\n plans: (policy.spec?.plans || []).map((plan: any) => ({\n tier: plan.tier,\n description: plan.description,\n limits: plan.limits,\n })),\n })),\n };\n\n res.json(filtered);\n } catch (error) {\n console.error('error fetching planpolicies:', error);\n if (error instanceof NotAllowedError) {\n res.status(403).json({ error: error.message });\n } else {\n res.status(500).json({ error: 'failed to fetch planpolicies' });\n }\n }\n });\n\n router.get('/planpolicies/:namespace/:name', async (req, res) => {\n try {\n const credentials = await httpAuth.credentials(req);\n\n const decision = await permissions.authorize(\n [{ permission: kuadrantPlanPolicyReadPermission }],\n { credentials }\n );\n\n if (decision[0].result !== AuthorizeResult.ALLOW) {\n throw new NotAllowedError('unauthorised');\n }\n\n const { namespace, name } = req.params;\n const data = await k8sClient.getCustomResource('extensions.kuadrant.io', 'v1alpha1', namespace, 'planpolicies', name);\n res.json(data);\n } catch (error) {\n console.error('error fetching planpolicy:', error);\n if (error instanceof NotAllowedError) {\n res.status(403).json({ error: error.message });\n } else {\n res.status(500).json({ error: 'failed to fetch planpolicy' });\n }\n }\n });\n\n // apikeyrequest crud endpoints\n const requestSchema = z.object({\n apiName: z.string(),\n apiNamespace: z.string(),\n planTier: z.string(),\n useCase: z.string().optional(),\n userEmail: z.string().optional(),\n });\n\n router.post('/requests', async (req, res) => {\n const parsed = requestSchema.safeParse(req.body);\n if (!parsed.success) {\n throw new InputError(parsed.error.toString());\n }\n\n try {\n const credentials = await httpAuth.credentials(req);\n const { apiName, apiNamespace, planTier, useCase, userEmail } = parsed.data;\n\n // extract userId from authenticated credentials, not from request body\n const { userEntityRef } = await getUserIdentity(req, httpAuth, userInfo);\n\n // check permission with resource reference (per-apiproduct access control)\n const resourceRef = `apiproduct:${apiNamespace}/${apiName}`;\n const decision = await permissions.authorize(\n [{\n permission: kuadrantApiKeyRequestCreatePermission,\n resourceRef,\n }],\n { credentials }\n );\n\n if (decision[0].result !== AuthorizeResult.ALLOW) {\n throw new NotAllowedError(`not authorised to request access to ${apiName}`);\n }\n const timestamp = new Date().toISOString();\n const randomSuffix = randomBytes(4).toString('hex');\n const userName = extractNameFromEntityRef(userEntityRef);\n const requestName = `${userName}-${apiName}-${randomSuffix}`.toLowerCase().replace(/[^a-z0-9-]/g, '-');\n\n const requestedBy: any = { userId: userEntityRef };\n if (userEmail) {\n requestedBy.email = userEmail;\n }\n\n const request = {\n apiVersion: 'extensions.kuadrant.io/v1alpha1',\n kind: 'APIKeyRequest',\n metadata: {\n name: requestName,\n namespace: apiNamespace,\n },\n spec: {\n apiName,\n apiNamespace,\n planTier,\n useCase: useCase || '',\n requestedBy,\n requestedAt: timestamp,\n },\n };\n\n const created = await k8sClient.createCustomResource(\n 'extensions.kuadrant.io',\n 'v1alpha1',\n apiNamespace,\n 'apikeyrequests',\n request,\n );\n\n // check if apiproduct has automatic approval mode\n try {\n const apiProduct = await k8sClient.getCustomResource(\n 'extensions.kuadrant.io',\n 'v1alpha1',\n apiNamespace,\n 'apiproducts',\n apiName,\n );\n\n if (apiProduct.spec?.approvalMode === 'automatic') {\n // automatically approve and create secret\n const apiKey = generateApiKey();\n const timestamp = Date.now();\n const userName = extractNameFromEntityRef(userEntityRef);\n const secretName = `${userName}-${apiName}-${timestamp}`\n .toLowerCase()\n .replace(/[^a-z0-9-]/g, '-');\n\n const secret = {\n apiVersion: 'v1',\n kind: 'Secret',\n metadata: {\n name: secretName,\n namespace: apiNamespace,\n labels: {\n app: apiName,\n },\n annotations: {\n 'secret.kuadrant.io/plan-id': planTier,\n 'secret.kuadrant.io/user-id': userEntityRef,\n },\n },\n stringData: {\n api_key: apiKey,\n },\n type: 'Opaque',\n };\n\n await k8sClient.createSecret(apiNamespace, secret);\n\n // get plan limits\n let planLimits: any = null;\n const plan = apiProduct.spec?.plans?.find((p: any) => p.tier === planTier);\n if (plan) {\n planLimits = plan.limits;\n }\n\n // fetch httproute to get hostname\n let apiHostname = `${apiName}.apps.example.com`;\n try {\n const httproute = await k8sClient.getCustomResource(\n 'gateway.networking.k8s.io',\n 'v1',\n apiNamespace,\n 'httproutes',\n apiName,\n );\n if (httproute.spec?.hostnames && httproute.spec.hostnames.length > 0) {\n apiHostname = httproute.spec.hostnames[0];\n }\n } catch (error) {\n console.warn('could not fetch httproute for hostname, using default:', error);\n }\n\n // update request status to approved\n const status = {\n phase: 'Approved',\n reviewedBy: 'system',\n reviewedAt: new Date().toISOString(),\n reason: 'automatic approval',\n apiKey,\n apiHostname,\n apiBasePath: '/api/v1',\n apiDescription: `${apiName} api`,\n planLimits,\n };\n\n await k8sClient.patchCustomResourceStatus(\n 'extensions.kuadrant.io',\n 'v1alpha1',\n apiNamespace,\n 'apikeyrequests',\n requestName,\n status,\n );\n }\n } catch (error) {\n console.warn('could not check approval mode or auto-approve:', error);\n // continue anyway - request was created successfully\n }\n\n res.status(201).json(created);\n } catch (error) {\n console.error('error creating api key request:', error);\n if (error instanceof NotAllowedError) {\n res.status(403).json({ error: error.message });\n } else {\n res.status(500).json({ error: 'failed to create api key request' });\n }\n }\n });\n\n router.get('/requests', async (req, res) => {\n try {\n const credentials = await httpAuth.credentials(req);\n\n // check if user can read all requests or only own\n const readAllDecision = await permissions.authorize(\n [{ permission: kuadrantApiKeyRequestReadAllPermission }],\n { credentials }\n );\n\n const canReadAll = readAllDecision[0].result === AuthorizeResult.ALLOW;\n\n if (!canReadAll) {\n // try read own permission\n const readOwnDecision = await permissions.authorize(\n [{ permission: kuadrantApiKeyRequestReadOwnPermission }],\n { credentials }\n );\n\n if (readOwnDecision[0].result !== AuthorizeResult.ALLOW) {\n throw new NotAllowedError('unauthorised');\n }\n }\n\n const status = req.query.status as string;\n const namespace = req.query.namespace as string;\n\n let data;\n if (namespace) {\n data = await k8sClient.listCustomResources('extensions.kuadrant.io', 'v1alpha1', 'apikeyrequests', namespace);\n } else {\n data = await k8sClient.listCustomResources('extensions.kuadrant.io', 'v1alpha1', 'apikeyrequests');\n }\n\n let filteredItems = data.items || [];\n\n // if user only has read.own permission, filter by api product ownership\n if (!canReadAll) {\n const { userEntityRef } = await getUserIdentity(req, httpAuth, userInfo);\n\n // get all apiproducts owned by this user\n const apiproducts = await k8sClient.listCustomResources('extensions.kuadrant.io', 'v1alpha1', 'apiproducts');\n const ownedApiProducts = (apiproducts.items || [])\n .filter((product: any) => {\n const owner = product.metadata?.annotations?.['backstage.io/owner'];\n return owner === userEntityRef;\n })\n .map((product: any) => product.metadata.name);\n\n // filter requests to only those for owned api products\n filteredItems = filteredItems.filter((req: any) =>\n ownedApiProducts.includes(req.spec?.apiName)\n );\n }\n\n if (status) {\n filteredItems = filteredItems.filter((req: any) => {\n const phase = req.status?.phase || 'Pending';\n return phase === status;\n });\n }\n\n res.json({ items: filteredItems });\n } catch (error) {\n console.error('error fetching api key requests:', error);\n if (error instanceof NotAllowedError) {\n res.status(403).json({ error: error.message });\n } else {\n res.status(500).json({ error: 'failed to fetch api key requests' });\n }\n }\n });\n\n router.get('/requests/my', async (req, res) => {\n try {\n const credentials = await httpAuth.credentials(req);\n\n const decision = await permissions.authorize(\n [{ permission: kuadrantApiKeyRequestReadOwnPermission }],\n { credentials }\n );\n\n if (decision[0].result !== AuthorizeResult.ALLOW) {\n throw new NotAllowedError('unauthorised');\n }\n\n // extract userId from authenticated credentials, not from query params\n const { userEntityRef } = await getUserIdentity(req, httpAuth, userInfo);\n const namespace = req.query.namespace as string;\n\n let data;\n if (namespace) {\n data = await k8sClient.listCustomResources('extensions.kuadrant.io', 'v1alpha1', 'apikeyrequests', namespace);\n } else {\n data = await k8sClient.listCustomResources('extensions.kuadrant.io', 'v1alpha1', 'apikeyrequests');\n }\n\n const filteredItems = (data.items || []).filter(\n (req: any) => req.spec?.requestedBy?.userId === userEntityRef\n );\n\n res.json({ items: filteredItems });\n } catch (error) {\n console.error('error fetching user api key requests:', error);\n if (error instanceof NotAllowedError) {\n res.status(403).json({ error: error.message });\n } else {\n res.status(500).json({ error: 'failed to fetch user api key requests' });\n }\n }\n });\n\n const approveRejectSchema = z.object({\n comment: z.string().optional(),\n });\n\n router.post('/requests/:namespace/:name/approve', async (req, res) => {\n const parsed = approveRejectSchema.safeParse(req.body);\n if (!parsed.success) {\n throw new InputError(parsed.error.toString());\n }\n\n try {\n const credentials = await httpAuth.credentials(req);\n const { userEntityRef } = await getUserIdentity(req, httpAuth, userInfo);\n\n const { namespace, name } = req.params;\n const { comment } = parsed.data;\n const reviewedBy = userEntityRef;\n\n const request = await k8sClient.getCustomResource(\n 'extensions.kuadrant.io',\n 'v1alpha1',\n namespace,\n 'apikeyrequests',\n name,\n );\n\n const spec = request.spec as any;\n\n // verify user owns/admins the apiproduct this request is for\n const apiProduct = await k8sClient.getCustomResource(\n 'extensions.kuadrant.io',\n 'v1alpha1',\n spec.apiNamespace,\n 'apiproducts',\n spec.apiName,\n );\n\n const owner = apiProduct.metadata?.annotations?.['backstage.io/owner'];\n // owner is already in entity ref format\n\n // try update all permission first (admin)\n const updateAllDecision = await permissions.authorize(\n [{ permission: kuadrantApiKeyRequestUpdateAllPermission }],\n { credentials },\n );\n\n if (updateAllDecision[0].result !== AuthorizeResult.ALLOW) {\n // fallback to update own permission\n const updateOwnDecision = await permissions.authorize(\n [{ permission: kuadrantApiKeyRequestUpdateOwnPermission }],\n { credentials },\n );\n\n if (updateOwnDecision[0].result !== AuthorizeResult.ALLOW) {\n throw new NotAllowedError('unauthorised');\n }\n\n // verify ownership of the apiproduct\n if (owner !== userEntityRef) {\n throw new NotAllowedError('you can only approve requests for your own api products');\n }\n }\n const apiKey = generateApiKey();\n const timestamp = Date.now();\n const userName = extractNameFromEntityRef(spec.requestedBy.userId);\n const secretName = `${userName}-${spec.apiName}-${timestamp}`\n .toLowerCase()\n .replace(/[^a-z0-9-]/g, '-');\n\n const secret = {\n apiVersion: 'v1',\n kind: 'Secret',\n metadata: {\n name: secretName,\n namespace: spec.apiNamespace,\n labels: {\n app: spec.apiName,\n },\n annotations: {\n 'secret.kuadrant.io/plan-id': spec.planTier,\n 'secret.kuadrant.io/user-id': spec.requestedBy.userId,\n },\n },\n stringData: {\n api_key: apiKey,\n },\n type: 'Opaque',\n };\n\n await k8sClient.createSecret(spec.apiNamespace, secret);\n\n // try to get plan limits from apiproduct or planpolicy\n let planLimits: any = null;\n try {\n const products = await k8sClient.listCustomResources('extensions.kuadrant.io', 'v1alpha1', 'apiproducts');\n const product = (products.items || []).find((p: any) =>\n p.metadata.name.includes(spec.apiName) || p.spec?.displayName?.toLowerCase().includes(spec.apiName.toLowerCase())\n );\n if (product) {\n const plan = product.spec?.plans?.find((p: any) => p.tier === spec.planTier);\n if (plan) {\n planLimits = plan.limits;\n }\n }\n } catch (e) {\n console.warn('could not fetch apiproduct for plan limits:', e);\n }\n\n if (!planLimits) {\n try {\n const policy = await k8sClient.getCustomResource(\n 'extensions.kuadrant.io',\n 'v1alpha1',\n spec.apiNamespace,\n 'planpolicies',\n `${spec.apiName}-plan`,\n );\n const plan = policy.spec?.plans?.find((p: any) => p.tier === spec.planTier);\n if (plan) {\n planLimits = plan.limits;\n }\n } catch (e) {\n console.warn('could not fetch planpolicy for plan limits:', e);\n }\n }\n\n // fetch httproute to get hostname\n let apiHostname = `${spec.apiName}.apps.example.com`;\n try {\n const httproute = await k8sClient.getCustomResource(\n 'gateway.networking.k8s.io',\n 'v1',\n spec.apiNamespace,\n 'httproutes',\n spec.apiName,\n );\n if (httproute.spec?.hostnames && httproute.spec.hostnames.length > 0) {\n apiHostname = httproute.spec.hostnames[0];\n }\n } catch (error) {\n console.warn('could not fetch httproute for hostname, using default:', error);\n }\n\n const status = {\n phase: 'Approved',\n reviewedBy,\n reviewedAt: new Date().toISOString(),\n reason: comment || 'approved',\n apiKey,\n apiHostname,\n apiBasePath: '/api/v1',\n apiDescription: `${spec.apiName} api`,\n planLimits,\n };\n\n await k8sClient.patchCustomResourceStatus(\n 'extensions.kuadrant.io',\n 'v1alpha1',\n namespace,\n 'apikeyrequests',\n name,\n status,\n );\n\n res.json({ secretName });\n } catch (error) {\n console.error('error approving api key request:', error);\n if (error instanceof NotAllowedError) {\n res.status(403).json({ error: error.message });\n } else {\n res.status(500).json({ error: 'failed to approve api key request' });\n }\n }\n });\n\n router.post('/requests/:namespace/:name/reject', async (req, res) => {\n const parsed = approveRejectSchema.safeParse(req.body);\n if (!parsed.success) {\n throw new InputError(parsed.error.toString());\n }\n\n try {\n const credentials = await httpAuth.credentials(req);\n const { userEntityRef } = await getUserIdentity(req, httpAuth, userInfo);\n\n const { namespace, name } = req.params;\n const { comment } = parsed.data;\n const reviewedBy = userEntityRef;\n\n // fetch request to get apiproduct info\n const request = await k8sClient.getCustomResource(\n 'extensions.kuadrant.io',\n 'v1alpha1',\n namespace,\n 'apikeyrequests',\n name,\n );\n\n const spec = request.spec as any;\n\n // verify user owns/admins the apiproduct this request is for\n const apiProduct = await k8sClient.getCustomResource(\n 'extensions.kuadrant.io',\n 'v1alpha1',\n spec.apiNamespace,\n 'apiproducts',\n spec.apiName,\n );\n\n const owner = apiProduct.metadata?.annotations?.['backstage.io/owner'];\n // owner is already in entity ref format\n\n // try update all permission first (admin)\n const updateAllDecision = await permissions.authorize(\n [{ permission: kuadrantApiKeyRequestUpdateAllPermission }],\n { credentials },\n );\n\n if (updateAllDecision[0].result !== AuthorizeResult.ALLOW) {\n // fallback to update own permission\n const updateOwnDecision = await permissions.authorize(\n [{ permission: kuadrantApiKeyRequestUpdateOwnPermission }],\n { credentials },\n );\n\n if (updateOwnDecision[0].result !== AuthorizeResult.ALLOW) {\n throw new NotAllowedError('unauthorised');\n }\n\n // verify ownership of the apiproduct\n if (owner !== userEntityRef) {\n throw new NotAllowedError('you can only reject requests for your own api products');\n }\n }\n\n const status = {\n phase: 'Rejected',\n reviewedBy,\n reviewedAt: new Date().toISOString(),\n reason: comment || 'rejected',\n };\n\n await k8sClient.patchCustomResourceStatus(\n 'extensions.kuadrant.io',\n 'v1alpha1',\n namespace,\n 'apikeyrequests',\n name,\n status,\n );\n\n res.status(204).send();\n } catch (error) {\n console.error('error rejecting api key request:', error);\n if (error instanceof NotAllowedError) {\n res.status(403).json({ error: error.message });\n } else {\n res.status(500).json({ error: 'failed to reject api key request' });\n }\n }\n });\n\n const bulkApproveSchema = z.object({\n requests: z.array(z.object({\n namespace: z.string(),\n name: z.string(),\n })),\n comment: z.string().optional(),\n });\n\n router.post('/requests/bulk-approve', async (req, res) => {\n const parsed = bulkApproveSchema.safeParse(req.body);\n if (!parsed.success) {\n throw new InputError(parsed.error.toString());\n }\n\n try {\n const credentials = await httpAuth.credentials(req);\n const { userEntityRef } = await getUserIdentity(req, httpAuth, userInfo);\n\n const decision = await permissions.authorize(\n [{ permission: kuadrantApiKeyRequestUpdateAllPermission }],\n { credentials },\n );\n\n if (decision[0].result !== AuthorizeResult.ALLOW) {\n throw new NotAllowedError('unauthorised');\n }\n\n const { requests, comment } = parsed.data;\n const reviewedBy = userEntityRef;\n const results = [];\n\n for (const reqRef of requests) {\n try {\n const request = await k8sClient.getCustomResource(\n 'extensions.kuadrant.io',\n 'v1alpha1',\n reqRef.namespace,\n 'apikeyrequests',\n reqRef.name,\n );\n\n const spec = request.spec as any;\n\n // verify user owns/admins the apiproduct this request is for\n const apiProduct = await k8sClient.getCustomResource(\n 'extensions.kuadrant.io',\n 'v1alpha1',\n spec.apiNamespace,\n 'apiproducts',\n spec.apiName,\n );\n\n const owner = apiProduct.metadata?.annotations?.['backstage.io/owner'];\n // owner is already in entity ref format\n\n // try update all permission first (admin)\n const updateAllDecision = await permissions.authorize(\n [{ permission: kuadrantApiProductUpdateAllPermission }],\n { credentials },\n );\n\n if (updateAllDecision[0].result !== AuthorizeResult.ALLOW) {\n // fallback to update own permission\n const updateOwnDecision = await permissions.authorize(\n [{ permission: kuadrantApiProductUpdateOwnPermission }],\n { credentials },\n );\n\n if (updateOwnDecision[0].result !== AuthorizeResult.ALLOW) {\n throw new NotAllowedError('unauthorised');\n }\n\n // verify ownership of the apiproduct\n if (owner !== userEntityRef) {\n throw new NotAllowedError('you can only approve requests for your own api products');\n }\n }\n const apiKey = generateApiKey();\n const timestamp = Date.now();\n const userName = extractNameFromEntityRef(spec.requestedBy.userId);\n const secretName = `${userName}-${spec.apiName}-${timestamp}`\n .toLowerCase()\n .replace(/[^a-z0-9-]/g, '-');\n\n const secret = {\n apiVersion: 'v1',\n kind: 'Secret',\n metadata: {\n name: secretName,\n namespace: spec.apiNamespace,\n labels: {\n app: spec.apiName,\n },\n annotations: {\n 'secret.kuadrant.io/plan-id': spec.planTier,\n 'secret.kuadrant.io/user-id': spec.requestedBy.userId,\n },\n },\n stringData: {\n api_key: apiKey,\n },\n type: 'Opaque',\n };\n\n await k8sClient.createSecret(spec.apiNamespace, secret);\n\n // try to get plan limits from apiproduct or planpolicy\n let planLimits: any = null;\n try {\n const products = await k8sClient.listCustomResources('extensions.kuadrant.io', 'v1alpha1', 'apiproducts');\n const product = (products.items || []).find((p: any) =>\n p.metadata.name.includes(spec.apiName) || p.spec?.displayName?.toLowerCase().includes(spec.apiName.toLowerCase())\n );\n if (product) {\n const plan = product.spec?.plans?.find((p: any) => p.tier === spec.planTier);\n if (plan) {\n planLimits = plan.limits;\n }\n }\n } catch (e) {\n console.warn('could not fetch apiproduct for plan limits:', e);\n }\n\n if (!planLimits) {\n try {\n const policy = await k8sClient.getCustomResource(\n 'extensions.kuadrant.io',\n 'v1alpha1',\n spec.apiNamespace,\n 'planpolicies',\n `${spec.apiName}-plan`,\n );\n const plan = policy.spec?.plans?.find((p: any) => p.tier === spec.planTier);\n if (plan) {\n planLimits = plan.limits;\n }\n } catch (e) {\n console.warn('could not fetch planpolicy for plan limits:', e);\n }\n }\n\n // fetch httproute to get hostname\n let apiHostname = `${spec.apiName}.apps.example.com`;\n try {\n const httproute = await k8sClient.getCustomResource(\n 'gateway.networking.k8s.io',\n 'v1',\n spec.apiNamespace,\n 'httproutes',\n spec.apiName,\n );\n if (httproute.spec?.hostnames && httproute.spec.hostnames.length > 0) {\n apiHostname = httproute.spec.hostnames[0];\n }\n } catch (error) {\n console.warn('could not fetch httproute for hostname, using default:', error);\n }\n\n const status = {\n phase: 'Approved',\n reviewedBy,\n reviewedAt: new Date().toISOString(),\n reason: comment || 'approved',\n apiKey,\n apiHostname,\n apiBasePath: '/api/v1',\n apiDescription: `${spec.apiName} api`,\n planLimits,\n };\n\n await k8sClient.patchCustomResourceStatus(\n 'extensions.kuadrant.io',\n 'v1alpha1',\n reqRef.namespace,\n 'apikeyrequests',\n reqRef.name,\n status,\n );\n\n results.push({ namespace: reqRef.namespace, name: reqRef.name, success: true, secretName });\n } catch (error) {\n console.error(`error approving request ${reqRef.namespace}/${reqRef.name}:`, error);\n results.push({\n namespace: reqRef.namespace,\n name: reqRef.name,\n success: false,\n error: error instanceof Error ? error.message : 'unknown error'\n });\n }\n }\n\n res.json({ results });\n } catch (error) {\n console.error('error in bulk approve:', error);\n if (error instanceof NotAllowedError) {\n res.status(403).json({ error: error.message });\n } else {\n res.status(500).json({ error: 'failed to bulk approve api key requests' });\n }\n }\n });\n\n router.post('/requests/bulk-reject', async (req, res) => {\n const parsed = bulkApproveSchema.safeParse(req.body);\n if (!parsed.success) {\n throw new InputError(parsed.error.toString());\n }\n\n try {\n const credentials = await httpAuth.credentials(req);\n const { userEntityRef } = await getUserIdentity(req, httpAuth, userInfo);\n\n const decision = await permissions.authorize(\n [{ permission: kuadrantApiKeyRequestUpdateAllPermission }],\n { credentials },\n );\n\n if (decision[0].result !== AuthorizeResult.ALLOW) {\n throw new NotAllowedError('unauthorised');\n }\n\n const { requests, comment } = parsed.data;\n const reviewedBy = userEntityRef;\n const results = [];\n\n for (const reqRef of requests) {\n try {\n // fetch request to get apiproduct info\n const request = await k8sClient.getCustomResource(\n 'extensions.kuadrant.io',\n 'v1alpha1',\n reqRef.namespace,\n 'apikeyrequests',\n reqRef.name,\n );\n\n const spec = request.spec as any;\n\n // verify user owns/admins the apiproduct this request is for\n const apiProduct = await k8sClient.getCustomResource(\n 'extensions.kuadrant.io',\n 'v1alpha1',\n spec.apiNamespace,\n 'apiproducts',\n spec.apiName,\n );\n\n const owner = apiProduct.metadata?.annotations?.['backstage.io/owner'];\n // owner is already in entity ref format\n\n // try update all permission first (admin)\n const updateAllDecision = await permissions.authorize(\n [{ permission: kuadrantApiProductUpdateAllPermission }],\n { credentials },\n );\n\n if (updateAllDecision[0].result !== AuthorizeResult.ALLOW) {\n // fallback to update own permission\n const updateOwnDecision = await permissions.authorize(\n [{ permission: kuadrantApiProductUpdateOwnPermission }],\n { credentials },\n );\n\n if (updateOwnDecision[0].result !== AuthorizeResult.ALLOW) {\n throw new NotAllowedError('unauthorised');\n }\n\n // verify ownership of the apiproduct\n if (owner !== userEntityRef) {\n throw new NotAllowedError('you can only reject requests for your own api products');\n }\n }\n\n const status = {\n phase: 'Rejected',\n reviewedBy,\n reviewedAt: new Date().toISOString(),\n reason: comment || 'rejected',\n };\n\n await k8sClient.patchCustomResourceStatus(\n 'extensions.kuadrant.io',\n 'v1alpha1',\n reqRef.namespace,\n 'apikeyrequests',\n reqRef.name,\n status,\n );\n\n results.push({ namespace: reqRef.namespace, name: reqRef.name, success: true });\n } catch (error) {\n console.error(`error rejecting request ${reqRef.namespace}/${reqRef.name}:`, error);\n results.push({\n namespace: reqRef.namespace,\n name: reqRef.name,\n success: false,\n error: error instanceof Error ? error.message : 'unknown error'\n });\n }\n }\n\n res.json({ results });\n } catch (error) {\n console.error('error in bulk reject:', error);\n if (error instanceof NotAllowedError) {\n res.status(403).json({ error: error.message });\n } else {\n res.status(500).json({ error: 'failed to bulk reject api key requests' });\n }\n }\n });\n\n router.delete('/requests/:namespace/:name', async (req, res) => {\n try {\n const credentials = await httpAuth.credentials(req);\n const { userEntityRef } = await getUserIdentity(req, httpAuth, userInfo);\n const { namespace, name } = req.params;\n\n // get request to verify ownership\n const request = await k8sClient.getCustomResource(\n 'extensions.kuadrant.io',\n 'v1alpha1',\n namespace,\n 'apikeyrequests',\n name,\n );\n\n const requestUserId = request.spec?.requestedBy?.userId;\n\n // check if user can delete all requests or just their own\n const deleteAllDecision = await permissions.authorize(\n [{ permission: kuadrantApiKeyRequestDeleteAllPermission }],\n { credentials }\n );\n\n const canDeleteAll = deleteAllDecision[0].result === AuthorizeResult.ALLOW;\n\n if (!canDeleteAll) {\n // check if user can delete their own requests\n const deleteOwnDecision = await permissions.authorize(\n [{ permission: kuadrantApiKeyRequestDeleteOwnPermission }],\n { credentials }\n );\n\n if (deleteOwnDecision[0].result !== AuthorizeResult.ALLOW) {\n throw new NotAllowedError('unauthorised');\n }\n\n // verify ownership\n if (requestUserId !== userEntityRef) {\n throw new NotAllowedError('you can only delete your own api key requests');\n }\n }\n\n // if request is approved, find and delete associated secret\n if (request.status?.phase === 'Approved') {\n try {\n const apiNamespace = request.spec?.apiNamespace;\n const apiName = request.spec?.apiName;\n const planTier = request.spec?.planTier;\n\n // list secrets in the api namespace and find the one with matching annotations\n const secrets = await k8sClient.listSecrets(apiNamespace);\n const matchingSecret = secrets.items?.find((s: any) => {\n const annotations = s.metadata?.annotations || {};\n return (\n annotations['secret.kuadrant.io/user-id'] === requestUserId &&\n annotations['secret.kuadrant.io/plan-id'] === planTier &&\n s.metadata?.labels?.app === apiName\n );\n });\n\n if (matchingSecret) {\n await k8sClient.deleteSecret(apiNamespace, matchingSecret.metadata.name);\n }\n } catch (error) {\n console.warn('failed to delete associated secret:', error);\n // continue with request deletion even if secret deletion fails\n }\n }\n\n await k8sClient.deleteCustomResource(\n 'extensions.kuadrant.io',\n 'v1alpha1',\n namespace,\n 'apikeyrequests',\n name,\n );\n res.status(204).send();\n } catch (error) {\n console.error('error deleting api key request:', error);\n if (error instanceof NotAllowedError) {\n res.status(403).json({ error: error.message });\n } else {\n res.status(500).json({ error: 'failed to delete api key request' });\n }\n }\n });\n\n router.patch('/requests/:namespace/:name', async (req, res) => {\n // whitelist allowed fields for patching\n const patchSchema = z.object({\n spec: z.object({\n useCase: z.string().optional(),\n planTier: z.string().optional(),\n }).partial(),\n });\n\n const parsed = patchSchema.safeParse(req.body);\n if (!parsed.success) {\n throw new InputError('invalid patch: ' + parsed.error.toString());\n }\n\n try {\n const credentials = await httpAuth.credentials(req);\n const { userEntityRef } = await getUserIdentity(req, httpAuth, userInfo);\n const { namespace, name } = req.params;\n\n // get existing request to check ownership and status\n const existing = await k8sClient.getCustomResource(\n 'extensions.kuadrant.io',\n 'v1alpha1',\n namespace,\n 'apikeyrequests',\n name,\n );\n\n const requestUserId = existing.spec?.requestedBy?.userId;\n const currentPhase = existing.status?.phase || 'Pending';\n\n // only pending requests can be edited\n if (currentPhase !== 'Pending') {\n throw new NotAllowedError('only pending requests can be edited');\n }\n\n // check if user can update all requests or just their own\n const updateAllDecision = await permissions.authorize(\n [{ permission: kuadrantApiKeyRequestUpdateAllPermission }],\n { credentials }\n );\n\n if (updateAllDecision[0].result !== AuthorizeResult.ALLOW) {\n // check if user can update their own requests\n const updateOwnDecision = await permissions.authorize(\n [{ permission: kuadrantApiKeyRequestUpdateOwnPermission }],\n { credentials }\n );\n\n if (updateOwnDecision[0].result !== AuthorizeResult.ALLOW) {\n throw new NotAllowedError('unauthorised');\n }\n\n // verify ownership\n if (requestUserId !== userEntityRef) {\n throw new NotAllowedError('you can only update your own api key requests');\n }\n }\n\n // apply validated patch\n const updated = await k8sClient.patchCustomResource(\n 'extensions.kuadrant.io',\n 'v1alpha1',\n namespace,\n 'apikeyrequests',\n name,\n parsed.data,\n );\n\n res.json(updated);\n } catch (error) {\n console.error('error updating api key request:', error);\n if (error instanceof NotAllowedError) {\n res.status(403).json({ error: error.message });\n } else if (error instanceof InputError) {\n res.status(400).json({ error: error.message });\n } else {\n res.status(500).json({ error: 'failed to update api key request' });\n }\n }\n });\n\n // expose permissions for backstage permission framework\n router.use(createPermissionIntegrationRouter({\n permissions: kuadrantPermissions,\n }));\n\n return router;\n}\n"],"names":["randomBytes","NotAllowedError","permissions","Router","cors","express","k8sClient","KuadrantK8sClient","kuadrantApiProductListPermission","AuthorizeResult","kuadrantApiProductReadAllPermission","kuadrantApiProductReadOwnPermission","kuadrantApiProductCreatePermission","InputError","getAPIProductEntityProvider","kuadrantApiProductDeleteAllPermission","kuadrantApiProductDeleteOwnPermission","z","kuadrantApiProductUpdateAllPermission","kuadrantApiProductUpdateOwnPermission","kuadrantPlanPolicyListPermission","kuadrantPlanPolicyReadPermission","kuadrantApiKeyRequestCreatePermission","timestamp","userName","kuadrantApiKeyRequestReadAllPermission","kuadrantApiKeyRequestReadOwnPermission","req","kuadrantApiKeyRequestUpdateAllPermission","kuadrantApiKeyRequestUpdateOwnPermission","kuadrantApiKeyRequestDeleteAllPermission","kuadrantApiKeyRequestDeleteOwnPermission","createPermissionIntegrationRouter","kuadrantPermissions"],"mappings":"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"}
1
+ {"version":3,"file":"router.cjs.js","sources":["../src/router.ts"],"sourcesContent":["import { HttpAuthService, RootConfigService, UserInfoService, PermissionsService } from '@backstage/backend-plugin-api';\nimport { InputError, NotAllowedError } from '@backstage/errors';\nimport { AuthorizeResult } from '@backstage/plugin-permission-common';\nimport { createPermissionIntegrationRouter } from '@backstage/plugin-permission-node';\nimport { z } from 'zod';\nimport express from 'express';\nimport Router from 'express-promise-router';\nimport cors from 'cors';\nimport { randomBytes } from 'crypto';\nimport { KuadrantK8sClient } from './k8s-client';\nimport { getAPIProductEntityProvider } from './module';\nimport {\n kuadrantPermissions,\n kuadrantPlanPolicyListPermission,\n kuadrantPlanPolicyReadPermission,\n kuadrantApiProductListPermission,\n kuadrantApiProductReadOwnPermission,\n kuadrantApiProductReadAllPermission,\n kuadrantApiProductCreatePermission,\n kuadrantApiProductUpdateOwnPermission,\n kuadrantApiProductUpdateAllPermission,\n kuadrantApiProductDeleteOwnPermission,\n kuadrantApiProductDeleteAllPermission,\n kuadrantApiKeyRequestCreatePermission,\n kuadrantApiKeyRequestReadOwnPermission,\n kuadrantApiKeyRequestReadAllPermission,\n kuadrantApiKeyRequestUpdateOwnPermission,\n kuadrantApiKeyRequestUpdateAllPermission,\n kuadrantApiKeyRequestDeleteOwnPermission,\n kuadrantApiKeyRequestDeleteAllPermission,\n} from './permissions';\n\nfunction generateApiKey(): string {\n return randomBytes(32).toString('hex');\n}\n\n/**\n * Extract a kubernetes-safe name from entity ref\n * e.g., \"user:default/alice\" -> \"alice\"\n * e.g., \"group:platform/api-owners\" -> \"api-owners\"\n */\nfunction extractNameFromEntityRef(entityRef: string): string {\n const parts = entityRef.split('/');\n return parts[parts.length - 1];\n}\n\nasync function getUserIdentity(req: express.Request, httpAuth: HttpAuthService, userInfo: UserInfoService): Promise<{\n userEntityRef: string;\n groups: string[];\n}> {\n const credentials = await httpAuth.credentials(req);\n\n if (!credentials || !credentials.principal) {\n throw new NotAllowedError('authentication required');\n }\n\n // get user info from credentials\n const info = await userInfo.getUserInfo(credentials);\n const groups = info.ownershipEntityRefs || [];\n\n console.log(`user identity resolved: userEntityRef=${info.userEntityRef}, groups=${groups.join(',')}`);\n return {\n userEntityRef: info.userEntityRef,\n groups\n };\n}\n\nexport async function createRouter({\n httpAuth,\n userInfo,\n config,\n permissions,\n}: {\n httpAuth: HttpAuthService;\n userInfo: UserInfoService;\n config: RootConfigService;\n permissions: PermissionsService;\n}): Promise<express.Router> {\n const router = Router();\n\n // enable cors for dev mode (allows frontend on :3000 to call backend on :7007)\n router.use(cors({\n origin: 'http://localhost:3000',\n credentials: true,\n }));\n\n router.use(express.json());\n\n const k8sClient = new KuadrantK8sClient(config);\n\n // apiproduct endpoints\n router.get('/apiproducts', async (req, res) => {\n try {\n const credentials = await httpAuth.credentials(req);\n\n const listDecision = await permissions.authorize(\n [{ permission: kuadrantApiProductListPermission }],\n { credentials }\n );\n\n if (listDecision[0].result !== AuthorizeResult.ALLOW) {\n throw new NotAllowedError('unauthorised');\n }\n\n const { userEntityRef } = await getUserIdentity(req, httpAuth, userInfo);\n const data = await k8sClient.listCustomResources('devportal.kuadrant.io', 'v1alpha1', 'apiproducts');\n\n // check if user has read all permission\n const readAllDecision = await permissions.authorize(\n [{ permission: kuadrantApiProductReadAllPermission }],\n { credentials }\n );\n\n if (readAllDecision[0].result === AuthorizeResult.ALLOW) {\n // admin - return all apiproducts\n res.json(data);\n } else {\n // owner - check read own permission and filter\n const readOwnDecision = await permissions.authorize(\n [{ permission: kuadrantApiProductReadOwnPermission }],\n { credentials }\n );\n\n if (readOwnDecision[0].result !== AuthorizeResult.ALLOW) {\n throw new NotAllowedError('unauthorised');\n }\n\n // filter to only owned apiproducts\n const ownedItems = (data.items || []).filter((item: any) => {\n const owner = item.metadata?.annotations?.['backstage.io/owner'];\n return owner === userEntityRef;\n });\n\n res.json({ ...data, items: ownedItems });\n }\n } catch (error) {\n console.error('error fetching apiproducts:', error);\n if (error instanceof NotAllowedError) {\n res.status(403).json({ error: error.message });\n } else {\n res.status(500).json({ error: 'failed to fetch apiproducts' });\n }\n }\n });\n\n router.get('/apiproducts/:namespace/:name', async (req, res) => {\n try {\n const credentials = await httpAuth.credentials(req);\n const { namespace, name } = req.params;\n\n // try read all permission first (admin)\n const readAllDecision = await permissions.authorize(\n [{ permission: kuadrantApiProductReadAllPermission }],\n { credentials }\n );\n\n if (readAllDecision[0].result !== AuthorizeResult.ALLOW) {\n // fallback to read own permission\n const readOwnDecision = await permissions.authorize(\n [{ permission: kuadrantApiProductReadOwnPermission }],\n { credentials }\n );\n\n if (readOwnDecision[0].result !== AuthorizeResult.ALLOW) {\n throw new NotAllowedError('unauthorised');\n }\n\n // verify ownership\n const { userEntityRef } = await getUserIdentity(req, httpAuth, userInfo);\n const data = await k8sClient.getCustomResource('devportal.kuadrant.io', 'v1alpha1', namespace, 'apiproducts', name);\n const owner = data.metadata?.annotations?.['backstage.io/owner'];\n // owner is already in entity ref format\n\n if (owner !== userEntityRef) {\n throw new NotAllowedError('you can only read your own api products');\n }\n\n res.json(data);\n } else {\n // admin - read any apiproduct\n const data = await k8sClient.getCustomResource('devportal.kuadrant.io', 'v1alpha1', namespace, 'apiproducts', name);\n res.json(data);\n }\n } catch (error) {\n console.error('error fetching apiproduct:', error);\n if (error instanceof NotAllowedError) {\n res.status(403).json({ error: error.message });\n } else {\n res.status(500).json({ error: 'failed to fetch apiproduct' });\n }\n }\n });\n\n router.post('/apiproducts', async (req, res) => {\n try {\n const credentials = await httpAuth.credentials(req);\n\n const decision = await permissions.authorize(\n [{ permission: kuadrantApiProductCreatePermission }],\n { credentials }\n );\n\n if (decision[0].result !== AuthorizeResult.ALLOW) {\n throw new NotAllowedError('unauthorised');\n }\n\n const { userEntityRef } = await getUserIdentity(req, httpAuth, userInfo);\n const apiProduct = req.body;\n const targetRef = apiProduct.spec?.targetRef;\n\n if (!targetRef?.name || !targetRef?.kind || !targetRef?.namespace) {\n throw new InputError('targetRef with name, kind, and namespace is required');\n }\n\n // derive namespace from httproute - apiproduct lives in same namespace as httproute\n const namespace = targetRef.namespace;\n apiProduct.metadata.namespace = namespace;\n\n // set ownership annotation (backstage-specific metadata)\n // note: creationTimestamp is automatically set by kubernetes api server\n if (!apiProduct.metadata.annotations) {\n apiProduct.metadata.annotations = {};\n }\n apiProduct.metadata.annotations['backstage.io/owner'] = userEntityRef;\n\n // temporary: populate plans from planpolicy until controller implements this\n // look up httproute and find planpolicy targeting it\n const httpRouteNamespace = namespace;\n const httpRouteName = targetRef.name;\n\n try {\n // list all planpolicies in the httproute's namespace\n const planPoliciesResponse = await k8sClient.listCustomResources(\n 'extensions.kuadrant.io',\n 'v1alpha1',\n 'planpolicies',\n httpRouteNamespace\n );\n\n // find planpolicy targeting this httproute\n const planPolicy = (planPoliciesResponse.items || []).find((pp: any) => {\n const ref = pp.spec?.targetRef;\n return ref?.kind === 'HTTPRoute' &&\n ref?.name === httpRouteName &&\n (!ref?.namespace || ref?.namespace === httpRouteNamespace);\n });\n\n if (planPolicy && planPolicy.spec?.plans) {\n // copy plans from planpolicy to apiproduct spec\n apiProduct.spec.plans = planPolicy.spec.plans.map((plan: any) => ({\n tier: plan.tier,\n description: plan.description,\n limits: plan.limits\n }));\n console.log(`copied ${apiProduct.spec.plans.length} plans from planpolicy ${planPolicy.metadata.name}`);\n } else {\n console.log(`no planpolicy found for httproute ${httpRouteNamespace}/${httpRouteName}`);\n }\n } catch (error) {\n console.warn('failed to populate plans from planpolicy:', error);\n // continue without plans rather than failing the creation\n }\n\n const created = await k8sClient.createCustomResource(\n 'devportal.kuadrant.io',\n 'v1alpha1',\n namespace,\n 'apiproducts',\n apiProduct,\n );\n\n // trigger immediate catalog sync\n const provider = getAPIProductEntityProvider();\n if (provider) {\n await provider.refresh();\n }\n\n res.status(201).json(created);\n } catch (error) {\n console.error('error creating apiproduct:', error);\n const errorMessage = error instanceof Error ? error.message : String(error);\n\n if (error instanceof NotAllowedError) {\n res.status(403).json({ error: error.message });\n } else if (error instanceof InputError) {\n res.status(400).json({ error: error.message });\n } else {\n // pass the detailed error message to the frontend\n res.status(500).json({ error: errorMessage });\n }\n }\n });\n\n router.delete('/apiproducts/:namespace/:name', async (req, res) => {\n try {\n const credentials = await httpAuth.credentials(req);\n const { namespace, name } = req.params;\n\n // try delete all permission first (admin)\n const deleteAllDecision = await permissions.authorize(\n [{ permission: kuadrantApiProductDeleteAllPermission }],\n { credentials }\n );\n\n if (deleteAllDecision[0].result !== AuthorizeResult.ALLOW) {\n // fallback to delete own permission\n const deleteOwnDecision = await permissions.authorize(\n [{ permission: kuadrantApiProductDeleteOwnPermission }],\n { credentials }\n );\n\n if (deleteOwnDecision[0].result !== AuthorizeResult.ALLOW) {\n throw new NotAllowedError('unauthorised');\n }\n\n // verify ownership before deleting\n const { userEntityRef } = await getUserIdentity(req, httpAuth, userInfo);\n const existing = await k8sClient.getCustomResource('devportal.kuadrant.io', 'v1alpha1', namespace, 'apiproducts', name);\n const owner = existing.metadata?.annotations?.['backstage.io/owner'];\n // owner is already in entity ref format\n\n if (owner !== userEntityRef) {\n throw new NotAllowedError('you can only delete your own api products');\n }\n }\n\n await k8sClient.deleteCustomResource(\n 'devportal.kuadrant.io',\n 'v1alpha1',\n namespace,\n 'apiproducts',\n name\n );\n\n // trigger immediate catalog sync\n const provider = getAPIProductEntityProvider();\n if (provider) {\n await provider.refresh();\n }\n\n res.status(204).send();\n } catch (error) {\n console.error('error deleting apiproduct:', error);\n if (error instanceof NotAllowedError) {\n res.status(403).json({ error: error.message });\n } else {\n res.status(500).json({ error: 'failed to delete apiproduct' });\n }\n }\n });\n\n // httproute endpoints\n router.get('/httproutes', async (req, res) => {\n try {\n const credentials = await httpAuth.credentials(req);\n\n const decision = await permissions.authorize(\n [{ permission: kuadrantApiProductListPermission }],\n { credentials }\n );\n\n if (decision[0].result !== AuthorizeResult.ALLOW) {\n throw new NotAllowedError('unauthorised');\n }\n\n const data = await k8sClient.listCustomResources('gateway.networking.k8s.io', 'v1', 'httproutes');\n\n res.json(data);\n } catch (error) {\n console.error('error fetching httproutes:', error);\n if (error instanceof NotAllowedError) {\n res.status(403).json({ error: error.message });\n } else {\n res.status(500).json({ error: 'failed to fetch httproutes' });\n }\n }\n });\n\n router.patch('/apiproducts/:namespace/:name', async (req, res) => {\n // whitelist allowed fields for patching\n const patchSchema = z.object({\n spec: z.object({\n displayName: z.string().optional(),\n description: z.string().optional(),\n version: z.string().optional(),\n publishStatus: z.enum(['Draft', 'Published']).optional(),\n approvalMode: z.enum(['automatic', 'manual']).optional(),\n tags: z.array(z.string()).optional(),\n contact: z.object({\n email: z.string().optional(),\n team: z.string().optional(),\n slack: z.string().optional(),\n }).partial().optional(),\n documentation: z.object({\n docsURL: z.string().optional(),\n openAPISpec: z.string().optional(),\n }).partial().optional(),\n }).partial(),\n });\n\n const parsed = patchSchema.safeParse(req.body);\n if (!parsed.success) {\n return res.status(400).json({ error: 'invalid patch: ' + parsed.error.toString() });\n }\n\n try {\n const credentials = await httpAuth.credentials(req);\n\n if (!credentials || !credentials.principal) {\n throw new NotAllowedError('authentication required');\n }\n\n const { namespace, name } = req.params;\n\n // try update all permission first (admin)\n const updateAllDecision = await permissions.authorize(\n [{ permission: kuadrantApiProductUpdateAllPermission }],\n { credentials }\n );\n\n if (updateAllDecision[0].result !== AuthorizeResult.ALLOW) {\n // fallback to update own permission\n const updateOwnDecision = await permissions.authorize(\n [{ permission: kuadrantApiProductUpdateOwnPermission }],\n { credentials }\n );\n\n if (updateOwnDecision[0].result !== AuthorizeResult.ALLOW) {\n throw new NotAllowedError('unauthorised');\n }\n\n // verify ownership\n const { userEntityRef } = await getUserIdentity(req, httpAuth, userInfo);\n const existing = await k8sClient.getCustomResource('devportal.kuadrant.io', 'v1alpha1', namespace, 'apiproducts', name);\n const owner = existing.metadata?.annotations?.['backstage.io/owner'];\n // owner is already in entity ref format\n\n if (owner !== userEntityRef) {\n throw new NotAllowedError('you can only update your own api products');\n }\n }\n\n // prevent modification of ownership annotation\n if (req.body.metadata?.annotations) {\n delete req.body.metadata.annotations['backstage.io/owner'];\n }\n\n const updated = await k8sClient.patchCustomResource(\n 'devportal.kuadrant.io',\n 'v1alpha1',\n namespace,\n 'apiproducts',\n name,\n parsed.data,\n );\n\n return res.json(updated);\n } catch (error) {\n console.error('error updating apiproduct:', error);\n const errorMessage = error instanceof Error ? error.message : String(error);\n\n if (error instanceof NotAllowedError) {\n return res.status(403).json({ error: error.message });\n } else if (error instanceof InputError) {\n return res.status(400).json({ error: error.message });\n } else {\n return res.status(500).json({ error: errorMessage });\n }\n }\n });\n\n // planpolicy endpoints\n router.get('/planpolicies', async (req, res) => {\n try {\n const credentials = await httpAuth.credentials(req);\n\n const decision = await permissions.authorize(\n [{ permission: kuadrantPlanPolicyListPermission }],\n { credentials }\n );\n\n if (decision[0].result !== AuthorizeResult.ALLOW) {\n throw new NotAllowedError('unauthorised');\n }\n\n const data = await k8sClient.listCustomResources('extensions.kuadrant.io', 'v1alpha1', 'planpolicies');\n\n // only expose minimal info needed for UI association\n const filtered = {\n items: (data.items || []).map((policy: any) => ({\n metadata: {\n name: policy.metadata.name,\n namespace: policy.metadata.namespace,\n },\n // only expose targetRef to allow UI to match PlanPolicy -> HTTPRoute\n targetRef: policy.spec?.targetRef ? {\n kind: policy.spec.targetRef.kind,\n name: policy.spec.targetRef.name,\n namespace: policy.spec.targetRef.namespace,\n } : undefined,\n // only expose plan tier info, no other spec details\n plans: (policy.spec?.plans || []).map((plan: any) => ({\n tier: plan.tier,\n description: plan.description,\n limits: plan.limits,\n })),\n })),\n };\n\n res.json(filtered);\n } catch (error) {\n console.error('error fetching planpolicies:', error);\n if (error instanceof NotAllowedError) {\n res.status(403).json({ error: error.message });\n } else {\n res.status(500).json({ error: 'failed to fetch planpolicies' });\n }\n }\n });\n\n router.get('/planpolicies/:namespace/:name', async (req, res) => {\n try {\n const credentials = await httpAuth.credentials(req);\n\n const decision = await permissions.authorize(\n [{ permission: kuadrantPlanPolicyReadPermission }],\n { credentials }\n );\n\n if (decision[0].result !== AuthorizeResult.ALLOW) {\n throw new NotAllowedError('unauthorised');\n }\n\n const { namespace, name } = req.params;\n const data = await k8sClient.getCustomResource('extensions.kuadrant.io', 'v1alpha1', namespace, 'planpolicies', name);\n res.json(data);\n } catch (error) {\n console.error('error fetching planpolicy:', error);\n if (error instanceof NotAllowedError) {\n res.status(403).json({ error: error.message });\n } else {\n res.status(500).json({ error: 'failed to fetch planpolicy' });\n }\n }\n });\n\n // apikey crud endpoints\n const requestSchema = z.object({\n apiProductName: z.string(), // name of the APIProduct\n namespace: z.string(), // namespace where both APIProduct and APIKey live\n planTier: z.string(),\n useCase: z.string().optional(),\n userEmail: z.string().optional(),\n });\n\n router.post('/requests', async (req, res) => {\n const parsed = requestSchema.safeParse(req.body);\n if (!parsed.success) {\n throw new InputError(parsed.error.toString());\n }\n\n try {\n const credentials = await httpAuth.credentials(req);\n const { apiProductName, namespace, planTier, useCase, userEmail } = parsed.data;\n\n // extract userId from authenticated credentials, not from request body\n const { userEntityRef } = await getUserIdentity(req, httpAuth, userInfo);\n\n // check permission with resource reference (per-apiproduct access control)\n const resourceRef = `apiproduct:${namespace}/${apiProductName}`;\n const decision = await permissions.authorize(\n [{\n permission: kuadrantApiKeyRequestCreatePermission,\n resourceRef,\n }],\n { credentials }\n );\n\n if (decision[0].result !== AuthorizeResult.ALLOW) {\n throw new NotAllowedError(`not authorised to request access to ${apiProductName}`);\n }\n const randomSuffix = randomBytes(4).toString('hex');\n const userName = extractNameFromEntityRef(userEntityRef);\n const requestName = `${userName}-${apiProductName}-${randomSuffix}`.toLowerCase().replace(/[^a-z0-9-]/g, '-');\n\n const requestedBy: any = { userId: userEntityRef };\n if (userEmail) {\n requestedBy.email = userEmail;\n }\n\n const request = {\n apiVersion: 'devportal.kuadrant.io/v1alpha1',\n kind: 'APIKey',\n metadata: {\n name: requestName,\n namespace,\n },\n spec: {\n apiProductRef: {\n name: apiProductName,\n },\n planTier,\n useCase: useCase || '',\n requestedBy,\n },\n };\n\n const created = await k8sClient.createCustomResource(\n 'devportal.kuadrant.io',\n 'v1alpha1',\n namespace,\n 'apikeys',\n request,\n );\n\n // check if apiproduct has automatic approval mode\n try {\n const apiProduct = await k8sClient.getCustomResource(\n 'devportal.kuadrant.io',\n 'v1alpha1',\n namespace,\n 'apiproducts',\n apiProductName,\n );\n\n if (apiProduct.spec?.approvalMode === 'automatic') {\n // automatically approve and create secret\n const apiKey = generateApiKey();\n const timestamp = Date.now();\n const userName = extractNameFromEntityRef(userEntityRef);\n const secretName = `${userName}-${apiProductName}-${timestamp}`\n .toLowerCase()\n .replace(/[^a-z0-9-]/g, '-');\n\n const secret = {\n apiVersion: 'v1',\n kind: 'Secret',\n metadata: {\n name: secretName,\n namespace,\n labels: {\n app: apiProductName,\n },\n annotations: {\n 'secret.kuadrant.io/plan-id': planTier,\n 'secret.kuadrant.io/user-id': userEntityRef,\n },\n },\n stringData: {\n api_key: apiKey,\n },\n type: 'Opaque',\n };\n\n await k8sClient.createSecret(namespace, secret);\n\n // get plan limits\n let planLimits: any = null;\n const plan = apiProduct.spec?.plans?.find((p: any) => p.tier === planTier);\n if (plan) {\n planLimits = plan.limits;\n }\n\n // fetch httproute to get hostname\n let apiHostname = `${apiProductName}.apps.example.com`;\n try {\n const httproute = await k8sClient.getCustomResource(\n 'gateway.networking.k8s.io',\n 'v1',\n namespace,\n 'httproutes',\n apiProductName,\n );\n if (httproute.spec?.hostnames && httproute.spec.hostnames.length > 0) {\n apiHostname = httproute.spec.hostnames[0];\n }\n } catch (error) {\n console.warn('could not fetch httproute for hostname, using default:', error);\n }\n\n // update request status to approved\n const status = {\n phase: 'Approved',\n reviewedBy: 'system',\n reviewedAt: new Date().toISOString(),\n reason: 'automatic approval',\n apiKey,\n apiHostname,\n apiBasePath: '/api/v1',\n apiDescription: `${apiProductName} api`,\n planLimits,\n };\n\n await k8sClient.patchCustomResourceStatus(\n 'devportal.kuadrant.io',\n 'v1alpha1',\n namespace,\n 'apikeys',\n requestName,\n status,\n );\n }\n } catch (error) {\n console.warn('could not check approval mode or auto-approve:', error);\n // continue anyway - request was created successfully\n }\n\n res.status(201).json(created);\n } catch (error) {\n console.error('error creating api key request:', error);\n if (error instanceof NotAllowedError) {\n res.status(403).json({ error: error.message });\n } else {\n res.status(500).json({ error: 'failed to create api key request' });\n }\n }\n });\n\n router.get('/requests', async (req, res) => {\n try {\n const credentials = await httpAuth.credentials(req);\n\n // check if user can read all requests or only own\n const readAllDecision = await permissions.authorize(\n [{ permission: kuadrantApiKeyRequestReadAllPermission }],\n { credentials }\n );\n\n const canReadAll = readAllDecision[0].result === AuthorizeResult.ALLOW;\n\n if (!canReadAll) {\n // try read own permission\n const readOwnDecision = await permissions.authorize(\n [{ permission: kuadrantApiKeyRequestReadOwnPermission }],\n { credentials }\n );\n\n if (readOwnDecision[0].result !== AuthorizeResult.ALLOW) {\n throw new NotAllowedError('unauthorised');\n }\n }\n\n const status = req.query.status as string;\n const namespace = req.query.namespace as string;\n\n let data;\n if (namespace) {\n data = await k8sClient.listCustomResources('devportal.kuadrant.io', 'v1alpha1', 'aPIKeys', namespace);\n } else {\n data = await k8sClient.listCustomResources('devportal.kuadrant.io', 'v1alpha1', 'aPIKeys');\n }\n\n let filteredItems = data.items || [];\n\n // if user only has read.own permission, filter by api product ownership\n if (!canReadAll) {\n const { userEntityRef } = await getUserIdentity(req, httpAuth, userInfo);\n\n // get all apiproducts owned by this user\n const apiproducts = await k8sClient.listCustomResources('devportal.kuadrant.io', 'v1alpha1', 'apiproducts');\n const ownedApiProducts = (apiproducts.items || [])\n .filter((product: any) => {\n const owner = product.metadata?.annotations?.['backstage.io/owner'];\n return owner === userEntityRef;\n })\n .map((product: any) => product.metadata.name);\n\n // filter requests to only those for owned api products\n filteredItems = filteredItems.filter((req: any) =>\n ownedApiProducts.includes(req.spec?.apiName)\n );\n }\n\n if (status) {\n filteredItems = filteredItems.filter((req: any) => {\n const phase = req.status?.phase || 'Pending';\n return phase === status;\n });\n }\n\n res.json({ items: filteredItems });\n } catch (error) {\n console.error('error fetching api key requests:', error);\n if (error instanceof NotAllowedError) {\n res.status(403).json({ error: error.message });\n } else {\n res.status(500).json({ error: 'failed to fetch api key requests' });\n }\n }\n });\n\n router.get('/requests/my', async (req, res) => {\n try {\n const credentials = await httpAuth.credentials(req);\n\n const decision = await permissions.authorize(\n [{ permission: kuadrantApiKeyRequestReadOwnPermission }],\n { credentials }\n );\n\n if (decision[0].result !== AuthorizeResult.ALLOW) {\n throw new NotAllowedError('unauthorised');\n }\n\n // extract userId from authenticated credentials, not from query params\n const { userEntityRef } = await getUserIdentity(req, httpAuth, userInfo);\n const namespace = req.query.namespace as string;\n\n let data;\n if (namespace) {\n data = await k8sClient.listCustomResources('devportal.kuadrant.io', 'v1alpha1', 'apikeys', namespace);\n } else {\n data = await k8sClient.listCustomResources('devportal.kuadrant.io', 'v1alpha1', 'apikeys');\n }\n\n const filteredItems = (data.items || []).filter(\n (req: any) => req.spec?.requestedBy?.userId === userEntityRef\n );\n\n res.json({ items: filteredItems });\n } catch (error) {\n console.error('error fetching user api key requests:', error);\n if (error instanceof NotAllowedError) {\n res.status(403).json({ error: error.message });\n } else {\n res.status(500).json({ error: 'failed to fetch user api key requests' });\n }\n }\n });\n\n const approveRejectSchema = z.object({\n comment: z.string().optional(),\n });\n\n router.post('/requests/:namespace/:name/approve', async (req, res) => {\n const parsed = approveRejectSchema.safeParse(req.body);\n if (!parsed.success) {\n throw new InputError(parsed.error.toString());\n }\n\n try {\n const credentials = await httpAuth.credentials(req);\n const { userEntityRef } = await getUserIdentity(req, httpAuth, userInfo);\n\n const { namespace, name } = req.params;\n const { comment } = parsed.data;\n const reviewedBy = userEntityRef;\n\n const request = await k8sClient.getCustomResource(\n 'devportal.kuadrant.io',\n 'v1alpha1',\n namespace,\n 'apikeys',\n name,\n );\n\n const spec = request.spec as any;\n const apiProductName = spec.apiProductRef?.name;\n\n if (!apiProductName) {\n throw new InputError('apiProductRef.name is required in APIKey spec');\n }\n\n // verify user owns/admins the apiproduct this request is for\n const apiProduct = await k8sClient.getCustomResource(\n 'devportal.kuadrant.io',\n 'v1alpha1',\n namespace,\n 'apiproducts',\n apiProductName,\n );\n\n const owner = apiProduct.metadata?.annotations?.['backstage.io/owner'];\n // owner is already in entity ref format\n\n // try update all permission first (admin)\n const updateAllDecision = await permissions.authorize(\n [{ permission: kuadrantApiKeyRequestUpdateAllPermission }],\n { credentials },\n );\n\n if (updateAllDecision[0].result !== AuthorizeResult.ALLOW) {\n // fallback to update own permission\n const updateOwnDecision = await permissions.authorize(\n [{ permission: kuadrantApiKeyRequestUpdateOwnPermission }],\n { credentials },\n );\n\n if (updateOwnDecision[0].result !== AuthorizeResult.ALLOW) {\n throw new NotAllowedError('unauthorised');\n }\n\n // verify ownership of the apiproduct\n if (owner !== userEntityRef) {\n throw new NotAllowedError('you can only approve requests for your own api products');\n }\n }\n const apiKey = generateApiKey();\n const timestamp = Date.now();\n const userName = extractNameFromEntityRef(spec.requestedBy.userId);\n const secretName = `${userName}-${apiProductName}-${timestamp}`\n .toLowerCase()\n .replace(/[^a-z0-9-]/g, '-');\n\n const secret = {\n apiVersion: 'v1',\n kind: 'Secret',\n metadata: {\n name: secretName,\n namespace,\n labels: {\n app: apiProductName,\n },\n annotations: {\n 'secret.kuadrant.io/plan-id': spec.planTier,\n 'secret.kuadrant.io/user-id': spec.requestedBy.userId,\n },\n },\n stringData: {\n api_key: apiKey,\n },\n type: 'Opaque',\n };\n\n await k8sClient.createSecret(namespace, secret);\n\n // try to get plan limits from apiproduct or planpolicy\n let planLimits: any = null;\n try {\n const products = await k8sClient.listCustomResources('devportal.kuadrant.io', 'v1alpha1', 'apiproducts');\n const product = (products.items || []).find((p: any) =>\n p.metadata.name.includes(apiProductName) || p.spec?.displayName?.toLowerCase().includes(apiProductName.toLowerCase())\n );\n if (product) {\n const plan = product.spec?.plans?.find((p: any) => p.tier === spec.planTier);\n if (plan) {\n planLimits = plan.limits;\n }\n }\n } catch (e) {\n console.warn('could not fetch apiproduct for plan limits:', e);\n }\n\n if (!planLimits) {\n try {\n const policy = await k8sClient.getCustomResource(\n 'extensions.kuadrant.io',\n 'v1alpha1',\n namespace,\n 'planpolicies',\n `${apiProductName}-plan`,\n );\n const plan = policy.spec?.plans?.find((p: any) => p.tier === spec.planTier);\n if (plan) {\n planLimits = plan.limits;\n }\n } catch (e) {\n console.warn('could not fetch planpolicy for plan limits:', e);\n }\n }\n\n // fetch httproute to get hostname\n let apiHostname = `${apiProductName}.apps.example.com`;\n try {\n const httproute = await k8sClient.getCustomResource(\n 'gateway.networking.k8s.io',\n 'v1',\n namespace,\n 'httproutes',\n apiProductName,\n );\n if (httproute.spec?.hostnames && httproute.spec.hostnames.length > 0) {\n apiHostname = httproute.spec.hostnames[0];\n }\n } catch (error) {\n console.warn('could not fetch httproute for hostname, using default:', error);\n }\n\n const status = {\n phase: 'Approved',\n reviewedBy,\n reviewedAt: new Date().toISOString(),\n reason: comment || 'approved',\n apiKey,\n apiHostname,\n apiBasePath: '/api/v1',\n apiDescription: `${apiProductName} api`,\n planLimits,\n };\n\n await k8sClient.patchCustomResourceStatus(\n 'devportal.kuadrant.io',\n 'v1alpha1',\n namespace,\n 'apikeys',\n name,\n status,\n );\n\n res.json({ secretName });\n } catch (error) {\n console.error('error approving api key request:', error);\n if (error instanceof NotAllowedError) {\n res.status(403).json({ error: error.message });\n } else {\n res.status(500).json({ error: 'failed to approve api key request' });\n }\n }\n });\n\n router.post('/requests/:namespace/:name/reject', async (req, res) => {\n const parsed = approveRejectSchema.safeParse(req.body);\n if (!parsed.success) {\n throw new InputError(parsed.error.toString());\n }\n\n try {\n const credentials = await httpAuth.credentials(req);\n const { userEntityRef } = await getUserIdentity(req, httpAuth, userInfo);\n\n const { namespace, name } = req.params;\n const { comment } = parsed.data;\n const reviewedBy = userEntityRef;\n\n // fetch request to get apiproduct info\n const request = await k8sClient.getCustomResource(\n 'devportal.kuadrant.io',\n 'v1alpha1',\n namespace,\n 'apikeys',\n name,\n );\n\n const spec = request.spec as any;\n const apiProductName = spec.apiProductRef?.name;\n\n if (!apiProductName) {\n throw new InputError('apiProductRef.name is required in APIKey spec');\n }\n\n // verify user owns/admins the apiproduct this request is for\n const apiProduct = await k8sClient.getCustomResource(\n 'devportal.kuadrant.io',\n 'v1alpha1',\n namespace,\n 'apiproducts',\n apiProductName,\n );\n\n const owner = apiProduct.metadata?.annotations?.['backstage.io/owner'];\n // owner is already in entity ref format\n\n // try update all permission first (admin)\n const updateAllDecision = await permissions.authorize(\n [{ permission: kuadrantApiKeyRequestUpdateAllPermission }],\n { credentials },\n );\n\n if (updateAllDecision[0].result !== AuthorizeResult.ALLOW) {\n // fallback to update own permission\n const updateOwnDecision = await permissions.authorize(\n [{ permission: kuadrantApiKeyRequestUpdateOwnPermission }],\n { credentials },\n );\n\n if (updateOwnDecision[0].result !== AuthorizeResult.ALLOW) {\n throw new NotAllowedError('unauthorised');\n }\n\n // verify ownership of the apiproduct\n if (owner !== userEntityRef) {\n throw new NotAllowedError('you can only reject requests for your own api products');\n }\n }\n\n const status = {\n phase: 'Rejected',\n reviewedBy,\n reviewedAt: new Date().toISOString(),\n reason: comment || 'rejected',\n };\n\n await k8sClient.patchCustomResourceStatus(\n 'devportal.kuadrant.io',\n 'v1alpha1',\n namespace,\n 'apikeys',\n name,\n status,\n );\n\n res.status(204).send();\n } catch (error) {\n console.error('error rejecting api key request:', error);\n if (error instanceof NotAllowedError) {\n res.status(403).json({ error: error.message });\n } else {\n res.status(500).json({ error: 'failed to reject api key request' });\n }\n }\n });\n\n const bulkApproveSchema = z.object({\n requests: z.array(z.object({\n namespace: z.string(),\n name: z.string(),\n })),\n comment: z.string().optional(),\n });\n\n router.post('/requests/bulk-approve', async (req, res) => {\n const parsed = bulkApproveSchema.safeParse(req.body);\n if (!parsed.success) {\n throw new InputError(parsed.error.toString());\n }\n\n try {\n const credentials = await httpAuth.credentials(req);\n const { userEntityRef } = await getUserIdentity(req, httpAuth, userInfo);\n\n const decision = await permissions.authorize(\n [{ permission: kuadrantApiKeyRequestUpdateAllPermission }],\n { credentials },\n );\n\n if (decision[0].result !== AuthorizeResult.ALLOW) {\n throw new NotAllowedError('unauthorised');\n }\n\n const { requests, comment } = parsed.data;\n const reviewedBy = userEntityRef;\n const results = [];\n\n for (const reqRef of requests) {\n try {\n const request = await k8sClient.getCustomResource(\n 'devportal.kuadrant.io',\n 'v1alpha1',\n reqRef.namespace,\n 'apikeys',\n reqRef.name,\n );\n\n const spec = request.spec as any;\n\n // verify user owns/admins the apiproduct this request is for\n const apiProduct = await k8sClient.getCustomResource(\n 'devportal.kuadrant.io',\n 'v1alpha1',\n spec.apiNamespace,\n 'apiproducts',\n spec.apiName,\n );\n\n const owner = apiProduct.metadata?.annotations?.['backstage.io/owner'];\n // owner is already in entity ref format\n\n // try update all permission first (admin)\n const updateAllDecision = await permissions.authorize(\n [{ permission: kuadrantApiProductUpdateAllPermission }],\n { credentials },\n );\n\n if (updateAllDecision[0].result !== AuthorizeResult.ALLOW) {\n // fallback to update own permission\n const updateOwnDecision = await permissions.authorize(\n [{ permission: kuadrantApiProductUpdateOwnPermission }],\n { credentials },\n );\n\n if (updateOwnDecision[0].result !== AuthorizeResult.ALLOW) {\n throw new NotAllowedError('unauthorised');\n }\n\n // verify ownership of the apiproduct\n if (owner !== userEntityRef) {\n throw new NotAllowedError('you can only approve requests for your own api products');\n }\n }\n const apiKey = generateApiKey();\n const timestamp = Date.now();\n const userName = extractNameFromEntityRef(spec.requestedBy.userId);\n const secretName = `${userName}-${spec.apiName}-${timestamp}`\n .toLowerCase()\n .replace(/[^a-z0-9-]/g, '-');\n\n const secret = {\n apiVersion: 'v1',\n kind: 'Secret',\n metadata: {\n name: secretName,\n namespace: spec.apiNamespace,\n labels: {\n app: spec.apiName,\n },\n annotations: {\n 'secret.kuadrant.io/plan-id': spec.planTier,\n 'secret.kuadrant.io/user-id': spec.requestedBy.userId,\n },\n },\n stringData: {\n api_key: apiKey,\n },\n type: 'Opaque',\n };\n\n await k8sClient.createSecret(spec.apiNamespace, secret);\n\n // try to get plan limits from apiproduct or planpolicy\n let planLimits: any = null;\n try {\n const products = await k8sClient.listCustomResources('devportal.kuadrant.io', 'v1alpha1', 'apiproducts');\n const product = (products.items || []).find((p: any) =>\n p.metadata.name.includes(spec.apiName) || p.spec?.displayName?.toLowerCase().includes(spec.apiName.toLowerCase())\n );\n if (product) {\n const plan = product.spec?.plans?.find((p: any) => p.tier === spec.planTier);\n if (plan) {\n planLimits = plan.limits;\n }\n }\n } catch (e) {\n console.warn('could not fetch apiproduct for plan limits:', e);\n }\n\n if (!planLimits) {\n try {\n const policy = await k8sClient.getCustomResource(\n 'devportal.kuadrant.io',\n 'v1alpha1',\n spec.apiNamespace,\n 'planpolicies',\n `${spec.apiName}-plan`,\n );\n const plan = policy.spec?.plans?.find((p: any) => p.tier === spec.planTier);\n if (plan) {\n planLimits = plan.limits;\n }\n } catch (e) {\n console.warn('could not fetch planpolicy for plan limits:', e);\n }\n }\n\n // fetch httproute to get hostname\n let apiHostname = `${spec.apiName}.apps.example.com`;\n try {\n const httproute = await k8sClient.getCustomResource(\n 'gateway.networking.k8s.io',\n 'v1',\n spec.apiNamespace,\n 'httproutes',\n spec.apiName,\n );\n if (httproute.spec?.hostnames && httproute.spec.hostnames.length > 0) {\n apiHostname = httproute.spec.hostnames[0];\n }\n } catch (error) {\n console.warn('could not fetch httproute for hostname, using default:', error);\n }\n\n const status = {\n phase: 'Approved',\n reviewedBy,\n reviewedAt: new Date().toISOString(),\n reason: comment || 'approved',\n apiKey,\n apiHostname,\n apiBasePath: '/api/v1',\n apiDescription: `${spec.apiName} api`,\n planLimits,\n };\n\n await k8sClient.patchCustomResourceStatus(\n 'devportal.kuadrant.io',\n 'v1alpha1',\n reqRef.namespace,\n 'apikeys',\n reqRef.name,\n status,\n );\n\n results.push({ namespace: reqRef.namespace, name: reqRef.name, success: true, secretName });\n } catch (error) {\n console.error(`error approving request ${reqRef.namespace}/${reqRef.name}:`, error);\n results.push({\n namespace: reqRef.namespace,\n name: reqRef.name,\n success: false,\n error: error instanceof Error ? error.message : 'unknown error'\n });\n }\n }\n\n res.json({ results });\n } catch (error) {\n console.error('error in bulk approve:', error);\n if (error instanceof NotAllowedError) {\n res.status(403).json({ error: error.message });\n } else {\n res.status(500).json({ error: 'failed to bulk approve api key requests' });\n }\n }\n });\n\n router.post('/requests/bulk-reject', async (req, res) => {\n const parsed = bulkApproveSchema.safeParse(req.body);\n if (!parsed.success) {\n throw new InputError(parsed.error.toString());\n }\n\n try {\n const credentials = await httpAuth.credentials(req);\n const { userEntityRef } = await getUserIdentity(req, httpAuth, userInfo);\n\n const decision = await permissions.authorize(\n [{ permission: kuadrantApiKeyRequestUpdateAllPermission }],\n { credentials },\n );\n\n if (decision[0].result !== AuthorizeResult.ALLOW) {\n throw new NotAllowedError('unauthorised');\n }\n\n const { requests, comment } = parsed.data;\n const reviewedBy = userEntityRef;\n const results = [];\n\n for (const reqRef of requests) {\n try {\n // fetch request to get apiproduct info\n const request = await k8sClient.getCustomResource(\n 'devportal.kuadrant.io',\n 'v1alpha1',\n reqRef.namespace,\n 'apikeys',\n reqRef.name,\n );\n\n const spec = request.spec as any;\n\n // verify user owns/admins the apiproduct this request is for\n const apiProduct = await k8sClient.getCustomResource(\n 'devportal.kuadrant.io',\n 'v1alpha1',\n spec.apiNamespace,\n 'apiproducts',\n spec.apiName,\n );\n\n const owner = apiProduct.metadata?.annotations?.['backstage.io/owner'];\n // owner is already in entity ref format\n\n // try update all permission first (admin)\n const updateAllDecision = await permissions.authorize(\n [{ permission: kuadrantApiProductUpdateAllPermission }],\n { credentials },\n );\n\n if (updateAllDecision[0].result !== AuthorizeResult.ALLOW) {\n // fallback to update own permission\n const updateOwnDecision = await permissions.authorize(\n [{ permission: kuadrantApiProductUpdateOwnPermission }],\n { credentials },\n );\n\n if (updateOwnDecision[0].result !== AuthorizeResult.ALLOW) {\n throw new NotAllowedError('unauthorised');\n }\n\n // verify ownership of the apiproduct\n if (owner !== userEntityRef) {\n throw new NotAllowedError('you can only reject requests for your own api products');\n }\n }\n\n const status = {\n phase: 'Rejected',\n reviewedBy,\n reviewedAt: new Date().toISOString(),\n reason: comment || 'rejected',\n };\n\n await k8sClient.patchCustomResourceStatus(\n 'devportal.kuadrant.io',\n 'v1alpha1',\n reqRef.namespace,\n 'apikeys',\n reqRef.name,\n status,\n );\n\n results.push({ namespace: reqRef.namespace, name: reqRef.name, success: true });\n } catch (error) {\n console.error(`error rejecting request ${reqRef.namespace}/${reqRef.name}:`, error);\n results.push({\n namespace: reqRef.namespace,\n name: reqRef.name,\n success: false,\n error: error instanceof Error ? error.message : 'unknown error'\n });\n }\n }\n\n res.json({ results });\n } catch (error) {\n console.error('error in bulk reject:', error);\n if (error instanceof NotAllowedError) {\n res.status(403).json({ error: error.message });\n } else {\n res.status(500).json({ error: 'failed to bulk reject api key requests' });\n }\n }\n });\n\n router.delete('/requests/:namespace/:name', async (req, res) => {\n try {\n const credentials = await httpAuth.credentials(req);\n const { userEntityRef } = await getUserIdentity(req, httpAuth, userInfo);\n const { namespace, name } = req.params;\n\n // get request to verify ownership\n const request = await k8sClient.getCustomResource(\n 'devportal.kuadrant.io',\n 'v1alpha1',\n namespace,\n 'apikeys',\n name,\n );\n\n const requestUserId = request.spec?.requestedBy?.userId;\n\n // check if user can delete all requests or just their own\n const deleteAllDecision = await permissions.authorize(\n [{ permission: kuadrantApiKeyRequestDeleteAllPermission }],\n { credentials }\n );\n\n const canDeleteAll = deleteAllDecision[0].result === AuthorizeResult.ALLOW;\n\n if (!canDeleteAll) {\n // check if user can delete their own requests\n const deleteOwnDecision = await permissions.authorize(\n [{ permission: kuadrantApiKeyRequestDeleteOwnPermission }],\n { credentials }\n );\n\n if (deleteOwnDecision[0].result !== AuthorizeResult.ALLOW) {\n throw new NotAllowedError('unauthorised');\n }\n\n // verify ownership\n if (requestUserId !== userEntityRef) {\n throw new NotAllowedError('you can only delete your own api key requests');\n }\n }\n\n // if request is approved, find and delete associated secret\n if (request.status?.phase === 'Approved') {\n try {\n const apiNamespace = request.spec?.apiNamespace;\n const apiName = request.spec?.apiName;\n const planTier = request.spec?.planTier;\n\n // list secrets in the api namespace and find the one with matching annotations\n const secrets = await k8sClient.listSecrets(apiNamespace);\n const matchingSecret = secrets.items?.find((s: any) => {\n const annotations = s.metadata?.annotations || {};\n return (\n annotations['secret.kuadrant.io/user-id'] === requestUserId &&\n annotations['secret.kuadrant.io/plan-id'] === planTier &&\n s.metadata?.labels?.app === apiName\n );\n });\n\n if (matchingSecret) {\n await k8sClient.deleteSecret(apiNamespace, matchingSecret.metadata.name);\n }\n } catch (error) {\n console.warn('failed to delete associated secret:', error);\n // continue with request deletion even if secret deletion fails\n }\n }\n\n await k8sClient.deleteCustomResource(\n 'devportal.kuadrant.io',\n 'v1alpha1',\n namespace,\n 'apikeys',\n name,\n );\n res.status(204).send();\n } catch (error) {\n console.error('error deleting api key request:', error);\n if (error instanceof NotAllowedError) {\n res.status(403).json({ error: error.message });\n } else {\n res.status(500).json({ error: 'failed to delete api key request' });\n }\n }\n });\n\n router.patch('/requests/:namespace/:name', async (req, res) => {\n // whitelist allowed fields for patching\n const patchSchema = z.object({\n spec: z.object({\n useCase: z.string().optional(),\n planTier: z.string().optional(),\n }).partial(),\n });\n\n const parsed = patchSchema.safeParse(req.body);\n if (!parsed.success) {\n throw new InputError('invalid patch: ' + parsed.error.toString());\n }\n\n try {\n const credentials = await httpAuth.credentials(req);\n const { userEntityRef } = await getUserIdentity(req, httpAuth, userInfo);\n const { namespace, name } = req.params;\n\n // get existing request to check ownership and status\n const existing = await k8sClient.getCustomResource(\n 'devportal.kuadrant.io',\n 'v1alpha1',\n namespace,\n 'apikeys',\n name,\n );\n\n const requestUserId = existing.spec?.requestedBy?.userId;\n const currentPhase = existing.status?.phase || 'Pending';\n\n // only pending requests can be edited\n if (currentPhase !== 'Pending') {\n throw new NotAllowedError('only pending requests can be edited');\n }\n\n // check if user can update all requests or just their own\n const updateAllDecision = await permissions.authorize(\n [{ permission: kuadrantApiKeyRequestUpdateAllPermission }],\n { credentials }\n );\n\n if (updateAllDecision[0].result !== AuthorizeResult.ALLOW) {\n // check if user can update their own requests\n const updateOwnDecision = await permissions.authorize(\n [{ permission: kuadrantApiKeyRequestUpdateOwnPermission }],\n { credentials }\n );\n\n if (updateOwnDecision[0].result !== AuthorizeResult.ALLOW) {\n throw new NotAllowedError('unauthorised');\n }\n\n // verify ownership\n if (requestUserId !== userEntityRef) {\n throw new NotAllowedError('you can only update your own api key requests');\n }\n }\n\n // apply validated patch\n const updated = await k8sClient.patchCustomResource(\n 'devportal.kuadrant.io',\n 'v1alpha1',\n namespace,\n 'apikeys',\n name,\n parsed.data,\n );\n\n res.json(updated);\n } catch (error) {\n console.error('error updating api key request:', error);\n if (error instanceof NotAllowedError) {\n res.status(403).json({ error: error.message });\n } else if (error instanceof InputError) {\n res.status(400).json({ error: error.message });\n } else {\n res.status(500).json({ error: 'failed to update api key request' });\n }\n }\n });\n\n // expose permissions for backstage permission framework\n router.use(createPermissionIntegrationRouter({\n permissions: kuadrantPermissions,\n }));\n\n return router;\n}\n"],"names":["randomBytes","NotAllowedError","permissions","Router","cors","express","k8sClient","KuadrantK8sClient","kuadrantApiProductListPermission","AuthorizeResult","kuadrantApiProductReadAllPermission","kuadrantApiProductReadOwnPermission","kuadrantApiProductCreatePermission","InputError","getAPIProductEntityProvider","kuadrantApiProductDeleteAllPermission","kuadrantApiProductDeleteOwnPermission","z","kuadrantApiProductUpdateAllPermission","kuadrantApiProductUpdateOwnPermission","kuadrantPlanPolicyListPermission","kuadrantPlanPolicyReadPermission","kuadrantApiKeyRequestCreatePermission","userName","kuadrantApiKeyRequestReadAllPermission","kuadrantApiKeyRequestReadOwnPermission","req","kuadrantApiKeyRequestUpdateAllPermission","kuadrantApiKeyRequestUpdateOwnPermission","kuadrantApiKeyRequestDeleteAllPermission","kuadrantApiKeyRequestDeleteOwnPermission","createPermissionIntegrationRouter","kuadrantPermissions"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kuadrant/kuadrant-backstage-plugin-backend",
3
- "version": "0.0.2-dev-8ec2009",
3
+ "version": "0.0.2-dev-90b0d1b",
4
4
  "license": "Apache-2.0",
5
5
  "repository": {
6
6
  "type": "git",