feat(extensions): migrate to NFS#2527
feat(extensions): migrate to NFS#2527debsmita1 wants to merge 1 commit intoredhat-developer:mainfrom
Conversation
Review Summary by QodoMigrate extensions plugin to new frontend system with dual app mode support
WalkthroughsDescription• **Migrated extensions plugin to new frontend system (NFS)**: Restructured the extensions workspace by moving the existing app to app-legacy and introducing a new NFS-based app package with modern frontend architecture • **Implemented comprehensive E2E test suite**: Added extensive Playwright tests for extensions catalog with support for multiple locales, filters, badges, and accessibility validation • **Created NFS app modules**: Developed sign-in, navigation, and app shell modules using the new frontend plugin API with lazy-loaded components and modular architecture • **Added alpha components and APIs**: Implemented API blueprints for extensionApi and dynamicPluginsInfoApi with dependency injection, and created NFS-compatible page and nav item blueprints • **Dual app mode support**: Added configuration for running both legacy and NFS apps with separate dev entry points, mock data, and test scripts • **Updated plugin dependencies**: Migrated from @backstage/app-defaults to @backstage/frontend-defaults and added NFS-specific dependencies • **Comprehensive documentation**: Updated README with setup instructions for both new frontend system and legacy configurations • **Fixed error page handling**: Simplified error page component usage by removing useApp() hook dependency Diagramflowchart LR
A["Legacy App<br/>app-legacy/"] -->|"preserved"| B["Original Routes<br/>& Plugins"]
C["NFS App<br/>app/"] -->|"new"| D["Frontend Modules<br/>nav, signIn, app"]
E["Extensions Plugin"] -->|"alpha exports"| F["NFS Blueprints<br/>page, navItem"]
E -->|"legacy support"| G["Dev Entry Points<br/>legacy.tsx, index.tsx"]
H["E2E Tests"] -->|"covers"| I["Both App Modes<br/>Legacy & NFS"]
J["Mock APIs"] -->|"provides"| K["Dev & Test Data<br/>extensions, plugins"]
File Changes1. workspaces/extensions/plugins/extensions/dev/__data__/mockExtensions.ts
|
Code Review by Qodo
1. Extensions plugin omitted
|
88dd164 to
d258b37
Compare
|
Important This PR includes changes that affect public-facing API. Please ensure you are adding/updating documentation for new features or behavior. Changed Packages
|
d258b37 to
b0b32e2
Compare
| import { createApp } from '@backstage/frontend-defaults'; | ||
| import { extensionsTranslationsModule } from '@red-hat-developer-hub/backstage-plugin-extensions/alpha'; | ||
| import { navModule } from './modules/nav'; | ||
| import { signInModule } from './modules/signIn'; | ||
|
|
||
| import { ScaffolderPage, scaffolderPlugin } from '@backstage/plugin-scaffolder'; | ||
| import { orgPlugin } from '@backstage/plugin-org'; | ||
| import { SearchPage } from '@backstage/plugin-search'; | ||
| import { | ||
| TechDocsIndexPage, | ||
| techdocsPlugin, | ||
| TechDocsReaderPage, | ||
| } from '@backstage/plugin-techdocs'; | ||
| import { TechDocsAddons } from '@backstage/plugin-techdocs-react'; | ||
| import { ReportIssue } from '@backstage/plugin-techdocs-module-addons-contrib'; | ||
| import { UserSettingsPage } from '@backstage/plugin-user-settings'; | ||
| import { | ||
| AlertDisplay, | ||
| OAuthRequestDialog, | ||
| SignInPage, | ||
| } from '@backstage/core-components'; | ||
| import { createApp } from '@backstage/app-defaults'; | ||
| import { AppRouter, FlatRoutes } from '@backstage/core-app-api'; | ||
| import { CatalogGraphPage } from '@backstage/plugin-catalog-graph'; | ||
| import { RequirePermission } from '@backstage/plugin-permission-react'; | ||
| import { catalogEntityCreatePermission } from '@backstage/plugin-catalog-common/alpha'; | ||
| import { githubAuthApiRef } from '@backstage/core-plugin-api'; | ||
|
|
||
| import { getAllThemes } from '@red-hat-developer-hub/backstage-plugin-theme'; | ||
|
|
||
| import { DynamicExtensionsPluginRouter as Extensions } from '@red-hat-developer-hub/backstage-plugin-extensions'; | ||
| import { extensionsTranslations } from '@red-hat-developer-hub/backstage-plugin-extensions/alpha'; | ||
|
|
||
| import { apis } from './apis'; | ||
| import { entityPage } from './components/catalog/EntityPage'; | ||
| import { searchPage } from './components/search/SearchPage'; | ||
| import { Root } from './components/Root'; | ||
|
|
||
| const app = createApp({ | ||
| apis, | ||
| __experimentalTranslations: { | ||
| availableLanguages: ['en', 'de', 'es', 'fr', 'it', 'ja'], | ||
| resources: [extensionsTranslations], | ||
| }, | ||
| bindRoutes({ bind }) { | ||
| bind(catalogPlugin.externalRoutes, { | ||
| createComponent: scaffolderPlugin.routes.root, | ||
| viewTechDoc: techdocsPlugin.routes.docRoot, | ||
| createFromTemplate: scaffolderPlugin.routes.selectedTemplate, | ||
| }); | ||
| bind(apiDocsPlugin.externalRoutes, { | ||
| registerApi: catalogImportPlugin.routes.importPage, | ||
| }); | ||
| bind(scaffolderPlugin.externalRoutes, { | ||
| registerComponent: catalogImportPlugin.routes.importPage, | ||
| viewTechDoc: techdocsPlugin.routes.docRoot, | ||
| }); | ||
| bind(orgPlugin.externalRoutes, { | ||
| catalogIndex: catalogPlugin.routes.catalogIndex, | ||
| }); | ||
| }, | ||
| components: { | ||
| SignInPage: props => ( | ||
| <SignInPage | ||
| {...props} | ||
| auto | ||
| providers={[ | ||
| 'guest', | ||
| { | ||
| id: 'github-auth-provider', | ||
| title: 'GitHub', | ||
| message: 'Sign in using GitHub', | ||
| apiRef: githubAuthApiRef, | ||
| }, | ||
| ]} | ||
| /> | ||
| ), | ||
| }, | ||
| themes: getAllThemes(), | ||
| export default createApp({ | ||
| features: [ navModule, extensionsTranslationsModule, signInModule], | ||
| }); |
There was a problem hiding this comment.
1. Extensions plugin omitted 🐞 Bug ✓ Correctness
The NFS app only registers nav/sign-in/translations modules and never registers the Extensions NFS plugin, so the Extensions page/nav-item extensions are not created in NFS mode and NFS e2e tests that navigate via the “Extensions” link will fail.
Agent Prompt
## Issue description
The NFS app (`workspaces/extensions/packages/app`) does not include the Extensions NFS plugin in its `createApp({ features: [...] })` list, so the Extensions page and sidebar nav item won’t be registered in NFS mode.
## Issue Context
The plugin README states that adding `extensionsPlugin` to the `features` array is what provides `/extensions` and the sidebar item. The NFS e2e tests navigate via an "Extensions" link.
## Fix Focus Areas
- workspaces/extensions/packages/app/src/App.tsx[17-24]
- workspaces/extensions/plugins/extensions/README.md[54-76]
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
| pluginsWithPermission: | ||
| - catalog | ||
| - extensions | ||
| admin: | ||
| superUsers: | ||
| - name: user:development/guest | ||
| users: | ||
| - name: user:development/guest |
There was a problem hiding this comment.
2. Guest rbac superuser 🐞 Bug ⛨ Security
The base app-config grants user:development/guest RBAC superuser/admin privileges, and the production config explicitly layers on top of app-config.yaml, meaning a production setup can unintentionally grant full admin to an unauthenticated guest.
Agent Prompt
## Issue description
`workspaces/extensions/app-config.yaml` grants RBAC superuser/admin privileges to the guest user. Since production config layers on top of `app-config.yaml`, this can leak into production.
## Issue Context
Guest auth is enabled in configs; RBAC superUsers should never include an unauthenticated guest identity in shared configs.
## Fix Focus Areas
- workspaces/extensions/app-config.yaml[135-147]
- workspaces/extensions/app-config.production.yaml[1-55]
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
b0b32e2 to
e7340c8
Compare
e7340c8 to
10e2ec8
Compare
|




Hey, I just made a Pull Request!
Resolves:
https://issues.redhat.com/browse/RHIDP-11629
Solution description:
✔️ Checklist