1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-09-10 17:53:36 +02:00

chore!: remove isAPI from userSchema response (#10060)

isAPI is not needed for responses, removing it from the system is much
more complex, so I had to cut it with a scalpel...
This commit is contained in:
Gastón Fournier 2025-05-30 11:37:50 +02:00 committed by GitHub
parent d8c83fb824
commit 898073878b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 33 additions and 32 deletions

View File

@ -3,7 +3,6 @@ import type { UserSchema } from './user-schema.js';
test('userSchema', () => { test('userSchema', () => {
const data: UserSchema = { const data: UserSchema = {
isAPI: false,
id: 1, id: 1,
username: 'admin', username: 'admin',
imageUrl: 'avatar', imageUrl: 'avatar',

View File

@ -13,13 +13,6 @@ export const userSchema = {
type: 'integer', type: 'integer',
example: 123, 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: { name: {
description: 'Name of the user', description: 'Name of the user',
type: 'string', type: 'string',

View File

@ -1,5 +1,5 @@
import type { ErrorObject } from 'ajv'; import type { ErrorObject } from 'ajv';
import Ajv from 'ajv'; import { Ajv } from 'ajv';
import { type SchemaId, schemas } from './index.js'; import { type SchemaId, schemas } from './index.js';
import { omitKeys } from '../util/index.js'; import { omitKeys } from '../util/index.js';
import { fromOpenApiValidationErrors } from '../error/bad-data-error.js'; import { fromOpenApiValidationErrors } from '../error/bad-data-error.js';
@ -8,7 +8,7 @@ export interface ISchemaValidationErrors<S = SchemaId> {
schema: S; schema: S;
errors: ErrorObject[]; errors: ErrorObject[];
} }
// @ts-expect-error: Does not expose constructor
const ajv = new Ajv({ const ajv = new Ajv({
schemas: Object.values(schemas).map((schema) => schemas: Object.values(schemas).map((schema) =>
omitKeys(schema, 'components'), omitKeys(schema, 'components'),
@ -34,9 +34,9 @@ export const addAjvSchema = (schemaObjects: any[]): any => {
}; };
export const validateSchema = <S = SchemaId>( export const validateSchema = <S = SchemaId>(
schema: S, schema: SchemaId,
data: unknown, data: unknown,
): ISchemaValidationErrors<S> | undefined => { ): ISchemaValidationErrors<SchemaId> | undefined => {
if (!ajv.validate(schema, data)) { if (!ajv.validate(schema, data)) {
return { return {
schema, schema,
@ -46,7 +46,7 @@ export const validateSchema = <S = SchemaId>(
}; };
export const throwOnInvalidSchema = <S = SchemaId>( export const throwOnInvalidSchema = <S = SchemaId>(
schema: S, schema: SchemaId,
data: object, data: object,
): void => { ): void => {
const validationErrors = validateSchema(schema, data); const validationErrors = validateSchema(schema, data);

View File

@ -495,7 +495,7 @@ export default class UserAdminController extends Controller {
const rootRoles = await this.accessService.getRootRoles(); const rootRoles = await this.accessService.getRootRoles();
const inviteLinks = await this.resetTokenService.getActiveInvitations(); const inviteLinks = await this.resetTokenService.getActiveInvitations();
const usersWithInviteLinks = users.map((user) => { const usersWithInviteLinks = users.map(({ isAPI, ...user }) => {
const inviteLink = inviteLinks[user.id] || ''; const inviteLink = inviteLinks[user.id] || '';
return { ...user, inviteLink }; return { ...user, inviteLink };
}); });
@ -533,7 +533,7 @@ export default class UserAdminController extends Controller {
200, 200,
res, res,
usersSearchSchema.$id, usersSearchSchema.$id,
serializeDates(users), serializeDates(users.map(({ isAPI, ...u }) => u)),
); );
} }
@ -580,7 +580,7 @@ export default class UserAdminController extends Controller {
res: Response<UserSchema>, res: Response<UserSchema>,
): Promise<void> { ): Promise<void> {
const { id } = req.params; const { id } = req.params;
const user = await this.userService.getUser(id); const { isAPI, ...user } = await this.userService.getUser(id);
this.openApiService.respondWithValidation( this.openApiService.respondWithValidation(
200, 200,
@ -621,8 +621,9 @@ export default class UserAdminController extends Controller {
? await this.userService.sendWelcomeEmail(createdUser, inviteLink) ? await this.userService.sendWelcomeEmail(createdUser, inviteLink)
: false; : false;
const { isAPI, ...user } = createdUser;
const responseData: CreateUserResponseSchema = { const responseData: CreateUserResponseSchema = {
...serializeDates(createdUser), ...serializeDates(user),
inviteLink, inviteLink,
emailSent, emailSent,
rootRole: normalizedRootRole, rootRole: normalizedRootRole,
@ -654,7 +655,7 @@ export default class UserAdminController extends Controller {
? Number(rootRole) ? Number(rootRole)
: (rootRole as RoleName); : (rootRole as RoleName);
const updateUser = await this.userService.updateUser( const { isAPI, ...updateUser } = await this.userService.updateUser(
{ {
id, id,
name, name,
@ -733,7 +734,9 @@ export default class UserAdminController extends Controller {
res: Response<UserAccessOverviewSchema>, res: Response<UserAccessOverviewSchema>,
): Promise<void> { ): Promise<void> {
const { project, environment } = req.query; 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); const rootRole = await this.accessService.getRootRoleForUser(user.id);
let projectRoles: IRoleWithPermissions[] = []; let projectRoles: IRoleWithPermissions[] = [];
if (project) { if (project) {

View File

@ -222,8 +222,9 @@ class UserController extends Controller {
await this.userFeedbackService.getAllUserFeedback(user); await this.userFeedbackService.getAllUserFeedback(user);
const splash = await this.userSplashService.getAllUserSplashes(user); const splash = await this.userSplashService.getAllUserSplashes(user);
const { isAPI, ...responseUser } = user;
const responseData: MeSchema = { const responseData: MeSchema = {
user: serializeDates(user), user: serializeDates(responseUser),
permissions, permissions,
feedback: serializeDates(feedback), feedback: serializeDates(feedback),
splash, splash,

View File

@ -62,10 +62,14 @@ export class SimplePasswordProvider extends Controller {
const { username, password } = req.body; const { username, password } = req.body;
const userAgent = req.get('user-agent'); const userAgent = req.get('user-agent');
const user = await this.userService.loginUser(username, password, { const { isAPI, ...user } = await this.userService.loginUser(
username,
password,
{
userAgent, userAgent,
ip: req.ip, ip: req.ip,
}); },
);
req.session.user = user; req.session.user = user;
this.openApiService.respondWithValidation( this.openApiService.respondWithValidation(
200, 200,

View File

@ -108,7 +108,8 @@ export class PublicInviteController extends Controller {
res.status(400).end(); res.status(400).end();
return; return;
} }
const user = await this.publicSignupTokenService.addTokenUser( const { isAPI, ...user } =
await this.publicSignupTokenService.addTokenUser(
token, token,
req.body, req.body,
req.audit, req.audit,

View File

@ -96,7 +96,7 @@ export class OpenApiService {
respondWithValidation<T, S = SchemaId>( respondWithValidation<T, S = SchemaId>(
status: number, status: number,
res: Response<T>, res: Response<T>,
schema: S, schema: SchemaId,
data: T, data: T,
headers: { [header: string]: string } = {}, headers: { [header: string]: string } = {},
): void { ): void {
@ -104,8 +104,8 @@ export class OpenApiService {
if (errors) { if (errors) {
this.logger.debug( this.logger.debug(
'Invalid response:', `Invalid response for ${res.req?.originalUrl || ''}:`,
JSON.stringify(errors, null, 4), errors,
); );
if (this.flagResolver.isEnabled('strictSchemaValidation')) { if (this.flagResolver.isEnabled('strictSchemaValidation')) {
throw new Error(JSON.stringify(errors, null, 4)); throw new Error(JSON.stringify(errors, null, 4));