big improvements

Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
This commit is contained in:
Patrik Oldsberg
2024-03-04 18:31:03 +01:00
parent 97b9d2bd35
commit a8c7b0da6a
7 changed files with 122 additions and 17 deletions
+1
View File
@@ -49,6 +49,7 @@
"@backstage/backend-plugin-api": "workspace:^",
"@backstage/config": "workspace:^",
"@backstage/config-loader": "workspace:^",
"@backstage/errors": "workspace:^",
"@backstage/plugin-app-node": "workspace:^",
"@backstage/types": "workspace:^",
"@types/express": "^4.17.6",
+7 -1
View File
@@ -65,8 +65,10 @@ export const appPlugin = createBackendPlugin({
config: coreServices.rootConfig,
database: coreServices.database,
httpRouter: coreServices.httpRouter,
auth: coreServices.auth,
httpAuth: coreServices.httpAuth,
},
async init({ logger, config, database, httpRouter }) {
async init({ logger, config, database, httpRouter, auth, httpAuth }) {
const appPackageName =
config.getOptionalString('app.packageName') ?? 'app';
@@ -76,11 +78,15 @@ export const appPlugin = createBackendPlugin({
logger: winstonLogger,
config,
database,
auth,
httpAuth,
appPackageName,
staticFallbackHandler,
schema,
});
httpRouter.use(router);
// Access control is handled within the router
httpRouter.addAuthPolicy({
allow: 'unauthenticated',
path: '/',
+84 -2
View File
@@ -38,6 +38,8 @@ import {
CACHE_CONTROL_REVALIDATE_CACHE,
} from '../lib/headers';
import { ConfigSchema } from '@backstage/config-loader';
import { AuthService, HttpAuthService } from '@backstage/backend-plugin-api';
import { AuthenticationError } from '@backstage/errors';
// express uses mime v1 while we only have types for mime v2
type Mime = { lookup(arg0: string): string };
@@ -46,6 +48,8 @@ type Mime = { lookup(arg0: string): string };
export interface RouterOptions {
config: Config;
logger: Logger;
auth?: AuthService;
httpAuth?: HttpAuthService;
/**
* If a database is provided it will be used to cache previously deployed static assets.
@@ -99,7 +103,14 @@ export interface RouterOptions {
export async function createRouter(
options: RouterOptions,
): Promise<express.Router> {
const { config, logger, appPackageName, staticFallbackHandler } = options;
const {
config,
logger,
appPackageName,
staticFallbackHandler,
auth,
httpAuth,
} = options;
const disableConfigInjection =
options.disableConfigInjection ??
@@ -154,9 +165,80 @@ export async function createRouter(
router.use(helmet.frameguard({ action: 'deny' }));
const publicDistDir = resolvePath(appDistDir, 'public');
const enablePublicEntryPoint = await fs.pathExists(publicDistDir);
/*
TODO:
- Cookie refresh
- Backend endpoint, /.backstage/v1-cookie
- Frontend provider
- Remove issueUserCookie from HttpAuthService and move to auth-node
- Move RedirectToRoot to auth-react
- Document index-public-experimental & how to use
- Logout? How do we clear the cookie?
*/
if (enablePublicEntryPoint && auth && httpAuth) {
const publicRouter = Router();
// TODO
// publicRouter.use(createCookieAuthRouter({ httpAuth }))
publicRouter.use(async (req, _res, next) => {
const credentials = await httpAuth.credentials(req, {
allow: ['user', 'service', 'none'],
allowLimitedAccess: true,
});
if (credentials.principal.type === 'none') {
next();
} else {
next('router');
}
});
publicRouter.post(
'*',
express.urlencoded({ extended: true }),
async (req, res, next) => {
if (req.body.type === 'sign-in') {
const credentials = await auth.authenticate(req.body.token);
if (!auth.isPrincipal(credentials, 'user')) {
throw new AuthenticationError('Invalid token, not a user');
}
await httpAuth.issueUserCookie(res, {
credentials,
});
// Resume as if it was a GET request towards the outer protected router, serving index.html
req.method = 'GET';
next('router');
} else {
throw new Error('Invalid POST request to /');
}
},
);
publicRouter.use(
await createEntryPointRouter({
logger: logger.child({ entry: 'public' }),
rootDir: publicDistDir,
assetStore: assetStore?.withNamespace('public'),
appConfigs, // TODO(Rugvip): We should not be including the full config here
}),
);
router.use(publicRouter);
}
router.use(
await createEntryPointRouter({
logger,
logger: logger.child({ entry: 'main' }),
rootDir: appDistDir,
assetStore,
staticFallbackHandler,