From 6f8f21fd488cfbf53a3526ffa138e40c3a43e27c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gast=C3=B3n=20Fournier?= Date: Fri, 3 Nov 2023 17:36:50 +0100 Subject: [PATCH] chore: expose type and more fixes (#5268) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Expose new interface while also getting rid of unneeded compiler ignores None of the changes should add new security risks, despite this report: > Code scanning results / CodeQL Failing after 4s — 2 new alerts including 2 high severity security vulnerabilities Not sure what that means, maybe a removed ignore... --- src/lib/middleware/demo-authentication.ts | 18 +++++++----------- src/lib/routes/proxy-api/index.ts | 4 ++-- src/lib/server-impl.ts | 3 ++- .../client-metrics/metrics-service-v2.ts | 2 +- src/lib/services/proxy-service.ts | 14 +++++++------- 5 files changed, 19 insertions(+), 22 deletions(-) diff --git a/src/lib/middleware/demo-authentication.ts b/src/lib/middleware/demo-authentication.ts index 0542a1838b..5a8a68dc9f 100644 --- a/src/lib/middleware/demo-authentication.ts +++ b/src/lib/middleware/demo-authentication.ts @@ -4,21 +4,22 @@ import { IUnleashServices } from '../types/services'; import { IUnleashConfig } from '../types/option'; import ApiUser from '../types/api-user'; import { ApiTokenType } from '../types/models/api-token'; +import { IAuthRequest } from 'lib/server-impl'; +import { IApiRequest } from 'lib/routes/unleash-types'; function demoAuthentication( app: Application, - basePath: string, // eslint-disable-line + basePath: string, { userService }: Pick, { authentication }: Pick, ): void { - app.post(`${basePath}/auth/demo/login`, async (req, res) => { + app.post(`${basePath}/auth/demo/login`, async (req: IAuthRequest, res) => { const { email } = req.body; try { const user = await userService.loginUserWithoutPassword( email, true, ); - // @ts-expect-error req.session.user = user; return res.status(200).json(user); } catch (e) { @@ -28,19 +29,15 @@ function demoAuthentication( } }); - app.use(`${basePath}/api/admin/`, (req, res, next) => { - // @ts-expect-error + app.use(`${basePath}/api/admin/`, (req: IAuthRequest, res, next) => { if (req.session.user?.email) { - // @ts-expect-error req.user = req.session.user; } next(); }); - app.use(`${basePath}/api/client`, (req, res, next) => { - // @ts-expect-error + app.use(`${basePath}/api/client`, (req: IApiRequest, res, next) => { if (!authentication.enableApiToken && !req.user) { - // @ts-expect-error req.user = new ApiUser({ tokenName: 'unauthed-default-client', permissions: [], @@ -53,8 +50,7 @@ function demoAuthentication( next(); }); - app.use(`${basePath}/api`, (req, res, next) => { - // @ts-expect-error + app.use(`${basePath}/api`, (req: IAuthRequest, res, next) => { if (req.user) { return next(); } diff --git a/src/lib/routes/proxy-api/index.ts b/src/lib/routes/proxy-api/index.ts index 9cf758617f..ecbe1694ad 100644 --- a/src/lib/routes/proxy-api/index.ts +++ b/src/lib/routes/proxy-api/index.ts @@ -7,7 +7,7 @@ import { NONE, } from '../../types'; import { Logger } from '../../logger'; -import ApiUser from '../../types/api-user'; +import { IApiUser } from '../../types/api-user'; import { ClientMetricsSchema, createRequestSchema, @@ -32,7 +32,7 @@ interface ApiUserRequest< ReqBody = any, ReqQuery = any, > extends Request { - user: ApiUser; + user: IApiUser; } type Services = Pick< diff --git a/src/lib/server-impl.ts b/src/lib/server-impl.ts index b13c83dc96..cf9ec44465 100644 --- a/src/lib/server-impl.ts +++ b/src/lib/server-impl.ts @@ -25,7 +25,7 @@ import ApiUser from './types/api-user'; import { Logger, LogLevel } from './logger'; import AuthenticationRequired from './types/authentication-required'; import Controller from './routes/controller'; -import { IAuthRequest } from './routes/unleash-types'; +import { IApiRequest, IAuthRequest } from './routes/unleash-types'; import { SimpleAuthSettings } from './types/settings/simple-auth-settings'; import { Knex } from 'knex'; import * as permissions from './types/permissions'; @@ -209,5 +209,6 @@ export type { IUser, IUnleashServices, IAuthRequest, + IApiRequest, SimpleAuthSettings, }; diff --git a/src/lib/services/client-metrics/metrics-service-v2.ts b/src/lib/services/client-metrics/metrics-service-v2.ts index 4a83f659a0..db10a706d1 100644 --- a/src/lib/services/client-metrics/metrics-service-v2.ts +++ b/src/lib/services/client-metrics/metrics-service-v2.ts @@ -13,7 +13,7 @@ import { secondsToMilliseconds, } from 'date-fns'; import { CLIENT_METRICS } from '../../types/events'; -import ApiUser from '../../types/api-user'; +import ApiUser, { IApiUser } from '../../types/api-user'; import { ALL } from '../../types/models/api-token'; import User from '../../types/user'; import { collapseHourlyMetrics } from '../../util/collapseHourlyMetrics'; diff --git a/src/lib/services/proxy-service.ts b/src/lib/services/proxy-service.ts index 2e3bf55922..40b8aaa5a7 100644 --- a/src/lib/services/proxy-service.ts +++ b/src/lib/services/proxy-service.ts @@ -1,7 +1,7 @@ import { IUnleashConfig, IUnleashServices, IUnleashStores } from '../types'; import { Logger } from '../logger'; import { ClientMetricsSchema, ProxyFeatureSchema } from '../openapi'; -import ApiUser from '../types/api-user'; +import ApiUser, { IApiUser } from '../types/api-user'; import { Context, InMemStorageProvider, @@ -61,7 +61,7 @@ export class ProxyService { } async getProxyFeatures( - token: ApiUser, + token: IApiUser, context: Context, ): Promise { const client = await this.clientForProxyToken(token); @@ -85,7 +85,7 @@ export class ProxyService { } async registerProxyMetrics( - token: ApiUser, + token: IApiUser, metrics: ClientMetricsSchema, ip: string, ): Promise { @@ -93,7 +93,7 @@ export class ProxyService { const environment = this.services.clientMetricsServiceV2.resolveMetricsEnvironment( - token, + token as ApiUser, metrics, ); @@ -103,7 +103,7 @@ export class ProxyService { ); } - private async clientForProxyToken(token: ApiUser): Promise { + private async clientForProxyToken(token: IApiUser): Promise { ProxyService.assertExpectedTokenType(token); let client = this.clients.get(token.secret); @@ -115,7 +115,7 @@ export class ProxyService { return client; } - private async createClientForProxyToken(token: ApiUser): Promise { + private async createClientForProxyToken(token: IApiUser): Promise { const repository = new ProxyRepository( this.config, this.stores, @@ -153,7 +153,7 @@ export class ProxyService { this.clients.forEach((promise) => promise.then((c) => c.destroy())); } - private static assertExpectedTokenType({ type }: ApiUser) { + private static assertExpectedTokenType({ type }: IApiUser) { if (!(type === ApiTokenType.FRONTEND || type === ApiTokenType.ADMIN)) { throw new InvalidTokenError(); }