diff --git a/src/lib/openapi/spec/user-schema.test.ts b/src/lib/openapi/spec/user-schema.test.ts index acf4c4d32d..946902e68e 100644 --- a/src/lib/openapi/spec/user-schema.test.ts +++ b/src/lib/openapi/spec/user-schema.test.ts @@ -3,7 +3,6 @@ import type { UserSchema } from './user-schema.js'; test('userSchema', () => { const data: UserSchema = { - isAPI: false, id: 1, username: 'admin', imageUrl: 'avatar', diff --git a/src/lib/openapi/spec/user-schema.ts b/src/lib/openapi/spec/user-schema.ts index dbd8bef37a..e7371638e8 100644 --- a/src/lib/openapi/spec/user-schema.ts +++ b/src/lib/openapi/spec/user-schema.ts @@ -13,13 +13,6 @@ export const userSchema = { type: 'integer', example: 123, }, - isAPI: { - description: - 'Deprecated in v5. Used internally to know which operations the user should be allowed to perform', - type: 'boolean', - example: true, - deprecated: true, - }, name: { description: 'Name of the user', type: 'string', diff --git a/src/lib/openapi/validate.ts b/src/lib/openapi/validate.ts index e7b5c1d4a3..367beac1cc 100644 --- a/src/lib/openapi/validate.ts +++ b/src/lib/openapi/validate.ts @@ -1,5 +1,5 @@ import type { ErrorObject } from 'ajv'; -import Ajv from 'ajv'; +import { Ajv } from 'ajv'; import { type SchemaId, schemas } from './index.js'; import { omitKeys } from '../util/index.js'; import { fromOpenApiValidationErrors } from '../error/bad-data-error.js'; @@ -8,7 +8,7 @@ export interface ISchemaValidationErrors { schema: S; errors: ErrorObject[]; } -// @ts-expect-error: Does not expose constructor + const ajv = new Ajv({ schemas: Object.values(schemas).map((schema) => omitKeys(schema, 'components'), @@ -34,9 +34,9 @@ export const addAjvSchema = (schemaObjects: any[]): any => { }; export const validateSchema = ( - schema: S, + schema: SchemaId, data: unknown, -): ISchemaValidationErrors | undefined => { +): ISchemaValidationErrors | undefined => { if (!ajv.validate(schema, data)) { return { schema, @@ -46,7 +46,7 @@ export const validateSchema = ( }; export const throwOnInvalidSchema = ( - schema: S, + schema: SchemaId, data: object, ): void => { const validationErrors = validateSchema(schema, data); diff --git a/src/lib/routes/admin-api/user-admin.ts b/src/lib/routes/admin-api/user-admin.ts index a8c27dfb92..5000cb18d3 100644 --- a/src/lib/routes/admin-api/user-admin.ts +++ b/src/lib/routes/admin-api/user-admin.ts @@ -495,7 +495,7 @@ export default class UserAdminController extends Controller { const rootRoles = await this.accessService.getRootRoles(); const inviteLinks = await this.resetTokenService.getActiveInvitations(); - const usersWithInviteLinks = users.map((user) => { + const usersWithInviteLinks = users.map(({ isAPI, ...user }) => { const inviteLink = inviteLinks[user.id] || ''; return { ...user, inviteLink }; }); @@ -533,7 +533,7 @@ export default class UserAdminController extends Controller { 200, res, usersSearchSchema.$id, - serializeDates(users), + serializeDates(users.map(({ isAPI, ...u }) => u)), ); } @@ -580,7 +580,7 @@ export default class UserAdminController extends Controller { res: Response, ): Promise { const { id } = req.params; - const user = await this.userService.getUser(id); + const { isAPI, ...user } = await this.userService.getUser(id); this.openApiService.respondWithValidation( 200, @@ -621,8 +621,9 @@ export default class UserAdminController extends Controller { ? await this.userService.sendWelcomeEmail(createdUser, inviteLink) : false; + const { isAPI, ...user } = createdUser; const responseData: CreateUserResponseSchema = { - ...serializeDates(createdUser), + ...serializeDates(user), inviteLink, emailSent, rootRole: normalizedRootRole, @@ -654,7 +655,7 @@ export default class UserAdminController extends Controller { ? Number(rootRole) : (rootRole as RoleName); - const updateUser = await this.userService.updateUser( + const { isAPI, ...updateUser } = await this.userService.updateUser( { id, name, @@ -733,7 +734,9 @@ export default class UserAdminController extends Controller { res: Response, ): Promise { const { project, environment } = req.query; - const user = await this.userService.getUser(req.params.id); + const { isAPI, ...user } = await this.userService.getUser( + req.params.id, + ); const rootRole = await this.accessService.getRootRoleForUser(user.id); let projectRoles: IRoleWithPermissions[] = []; if (project) { diff --git a/src/lib/routes/admin-api/user/user.ts b/src/lib/routes/admin-api/user/user.ts index b286a72db6..736e7c5834 100644 --- a/src/lib/routes/admin-api/user/user.ts +++ b/src/lib/routes/admin-api/user/user.ts @@ -222,8 +222,9 @@ class UserController extends Controller { await this.userFeedbackService.getAllUserFeedback(user); const splash = await this.userSplashService.getAllUserSplashes(user); + const { isAPI, ...responseUser } = user; const responseData: MeSchema = { - user: serializeDates(user), + user: serializeDates(responseUser), permissions, feedback: serializeDates(feedback), splash, diff --git a/src/lib/routes/auth/simple-password-provider.ts b/src/lib/routes/auth/simple-password-provider.ts index 8e40a87695..0a77020f5b 100644 --- a/src/lib/routes/auth/simple-password-provider.ts +++ b/src/lib/routes/auth/simple-password-provider.ts @@ -62,10 +62,14 @@ export class SimplePasswordProvider extends Controller { const { username, password } = req.body; const userAgent = req.get('user-agent'); - const user = await this.userService.loginUser(username, password, { - userAgent, - ip: req.ip, - }); + const { isAPI, ...user } = await this.userService.loginUser( + username, + password, + { + userAgent, + ip: req.ip, + }, + ); req.session.user = user; this.openApiService.respondWithValidation( 200, diff --git a/src/lib/routes/public-invite.ts b/src/lib/routes/public-invite.ts index 973505e16b..28e1acc1b8 100644 --- a/src/lib/routes/public-invite.ts +++ b/src/lib/routes/public-invite.ts @@ -108,11 +108,12 @@ export class PublicInviteController extends Controller { res.status(400).end(); return; } - const user = await this.publicSignupTokenService.addTokenUser( - token, - req.body, - req.audit, - ); + const { isAPI, ...user } = + await this.publicSignupTokenService.addTokenUser( + token, + req.body, + req.audit, + ); this.openApiService.respondWithValidation( 201, res, diff --git a/src/lib/services/openapi-service.ts b/src/lib/services/openapi-service.ts index 66fc7ee6b0..788d861bbc 100644 --- a/src/lib/services/openapi-service.ts +++ b/src/lib/services/openapi-service.ts @@ -96,7 +96,7 @@ export class OpenApiService { respondWithValidation( status: number, res: Response, - schema: S, + schema: SchemaId, data: T, headers: { [header: string]: string } = {}, ): void { @@ -104,8 +104,8 @@ export class OpenApiService { if (errors) { this.logger.debug( - 'Invalid response:', - JSON.stringify(errors, null, 4), + `Invalid response for ${res.req?.originalUrl || ''}:`, + errors, ); if (this.flagResolver.isEnabled('strictSchemaValidation')) { throw new Error(JSON.stringify(errors, null, 4));