1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-07-26 13:48:33 +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', () => {
const data: UserSchema = {
isAPI: false,
id: 1,
username: 'admin',
imageUrl: 'avatar',

View File

@ -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',

View File

@ -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<S = SchemaId> {
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 = <S = SchemaId>(
schema: S,
schema: SchemaId,
data: unknown,
): ISchemaValidationErrors<S> | undefined => {
): ISchemaValidationErrors<SchemaId> | undefined => {
if (!ajv.validate(schema, data)) {
return {
schema,
@ -46,7 +46,7 @@ export const validateSchema = <S = SchemaId>(
};
export const throwOnInvalidSchema = <S = SchemaId>(
schema: S,
schema: SchemaId,
data: object,
): void => {
const validationErrors = validateSchema(schema, data);

View File

@ -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<UserSchema>,
): Promise<void> {
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<UserAccessOverviewSchema>,
): Promise<void> {
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) {

View File

@ -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,

View File

@ -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,

View File

@ -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,

View File

@ -96,7 +96,7 @@ export class OpenApiService {
respondWithValidation<T, S = SchemaId>(
status: number,
res: Response<T>,
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));