mirror of
https://github.com/Unleash/unleash.git
synced 2025-06-04 01:18:20 +02:00
refactor: add OpenAPI schema to UI config controller (#1681)
This commit is contained in:
parent
cbffe0eda0
commit
09a6b578bf
@ -18,10 +18,12 @@ import { patchesSchema } from './spec/patches-schema';
|
|||||||
import { strategySchema } from './spec/strategy-schema';
|
import { strategySchema } from './spec/strategy-schema';
|
||||||
import { tagSchema } from './spec/tag-schema';
|
import { tagSchema } from './spec/tag-schema';
|
||||||
import { tagsSchema } from './spec/tags-schema';
|
import { tagsSchema } from './spec/tags-schema';
|
||||||
|
import { uiConfigSchema } from './spec/ui-config-schema';
|
||||||
import { updateFeatureSchema } from './spec/update-feature-schema';
|
import { updateFeatureSchema } from './spec/update-feature-schema';
|
||||||
import { updateStrategySchema } from './spec/update-strategy-schema';
|
import { updateStrategySchema } from './spec/update-strategy-schema';
|
||||||
import { variantSchema } from './spec/variant-schema';
|
import { variantSchema } from './spec/variant-schema';
|
||||||
import { variantsSchema } from './spec/variants-schema';
|
import { variantsSchema } from './spec/variants-schema';
|
||||||
|
import { versionSchema } from './spec/version-schema';
|
||||||
|
|
||||||
// Schemas must have $id property on the form "#/components/schemas/mySchema".
|
// Schemas must have $id property on the form "#/components/schemas/mySchema".
|
||||||
export type SchemaId = typeof schemas[keyof typeof schemas]['$id'];
|
export type SchemaId = typeof schemas[keyof typeof schemas]['$id'];
|
||||||
@ -57,10 +59,12 @@ export const schemas = {
|
|||||||
strategySchema,
|
strategySchema,
|
||||||
tagSchema,
|
tagSchema,
|
||||||
tagsSchema,
|
tagsSchema,
|
||||||
|
uiConfigSchema,
|
||||||
updateFeatureSchema,
|
updateFeatureSchema,
|
||||||
updateStrategySchema,
|
updateStrategySchema,
|
||||||
variantSchema,
|
variantSchema,
|
||||||
variantsSchema,
|
variantsSchema,
|
||||||
|
versionSchema,
|
||||||
};
|
};
|
||||||
|
|
||||||
export const createRequestSchema = (
|
export const createRequestSchema = (
|
||||||
|
24
src/lib/openapi/spec/ui-config-schema.test.ts
Normal file
24
src/lib/openapi/spec/ui-config-schema.test.ts
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
import { validateSchema } from '../validate';
|
||||||
|
import { UiConfigSchema } from './ui-config-schema';
|
||||||
|
|
||||||
|
test('uiConfigSchema', () => {
|
||||||
|
const data: UiConfigSchema = {
|
||||||
|
slogan: 'a',
|
||||||
|
version: 'a',
|
||||||
|
unleashUrl: 'a',
|
||||||
|
baseUriPath: 'a',
|
||||||
|
disablePasswordAuth: false,
|
||||||
|
segmentValuesLimit: 0,
|
||||||
|
strategySegmentsLimit: 0,
|
||||||
|
versionInfo: {
|
||||||
|
current: {},
|
||||||
|
latest: {},
|
||||||
|
isLatest: true,
|
||||||
|
instanceId: 'a',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
expect(
|
||||||
|
validateSchema('#/components/schemas/uiConfigSchema', data),
|
||||||
|
).toBeUndefined();
|
||||||
|
});
|
76
src/lib/openapi/spec/ui-config-schema.ts
Normal file
76
src/lib/openapi/spec/ui-config-schema.ts
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
import { FromSchema } from 'json-schema-to-ts';
|
||||||
|
import { versionSchema } from './version-schema';
|
||||||
|
|
||||||
|
export const uiConfigSchema = {
|
||||||
|
$id: '#/components/schemas/uiConfigSchema',
|
||||||
|
type: 'object',
|
||||||
|
additionalProperties: false,
|
||||||
|
required: [
|
||||||
|
'version',
|
||||||
|
'unleashUrl',
|
||||||
|
'baseUriPath',
|
||||||
|
'versionInfo',
|
||||||
|
'disablePasswordAuth',
|
||||||
|
'segmentValuesLimit',
|
||||||
|
'strategySegmentsLimit',
|
||||||
|
],
|
||||||
|
properties: {
|
||||||
|
slogan: {
|
||||||
|
type: 'string',
|
||||||
|
},
|
||||||
|
name: {
|
||||||
|
type: 'string',
|
||||||
|
},
|
||||||
|
version: {
|
||||||
|
type: 'string',
|
||||||
|
},
|
||||||
|
unleashUrl: {
|
||||||
|
type: 'string',
|
||||||
|
},
|
||||||
|
baseUriPath: {
|
||||||
|
type: 'string',
|
||||||
|
},
|
||||||
|
disablePasswordAuth: {
|
||||||
|
type: 'boolean',
|
||||||
|
},
|
||||||
|
segmentValuesLimit: {
|
||||||
|
type: 'number',
|
||||||
|
},
|
||||||
|
strategySegmentsLimit: {
|
||||||
|
type: 'number',
|
||||||
|
},
|
||||||
|
flags: {
|
||||||
|
type: 'object',
|
||||||
|
additionalProperties: {
|
||||||
|
type: 'boolean',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
links: {
|
||||||
|
type: 'array',
|
||||||
|
items: {
|
||||||
|
type: 'object',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
authenticationType: {
|
||||||
|
type: 'string',
|
||||||
|
enum: [
|
||||||
|
'open-source',
|
||||||
|
'demo',
|
||||||
|
'enterprise',
|
||||||
|
'hosted',
|
||||||
|
'custom',
|
||||||
|
'none',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
versionInfo: {
|
||||||
|
$ref: '#/components/schemas/versionSchema',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
schemas: {
|
||||||
|
versionSchema,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
} as const;
|
||||||
|
|
||||||
|
export type UiConfigSchema = FromSchema<typeof uiConfigSchema>;
|
43
src/lib/openapi/spec/version-schema.ts
Normal file
43
src/lib/openapi/spec/version-schema.ts
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
import { FromSchema } from 'json-schema-to-ts';
|
||||||
|
|
||||||
|
export const versionSchema = {
|
||||||
|
$id: '#/components/schemas/versionSchema',
|
||||||
|
type: 'object',
|
||||||
|
additionalProperties: false,
|
||||||
|
required: ['current', 'latest', 'isLatest', 'instanceId'],
|
||||||
|
properties: {
|
||||||
|
current: {
|
||||||
|
type: 'object',
|
||||||
|
additionalProperties: false,
|
||||||
|
properties: {
|
||||||
|
oss: {
|
||||||
|
type: 'string',
|
||||||
|
},
|
||||||
|
enterprise: {
|
||||||
|
type: 'string',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
latest: {
|
||||||
|
type: 'object',
|
||||||
|
additionalProperties: false,
|
||||||
|
properties: {
|
||||||
|
oss: {
|
||||||
|
type: 'string',
|
||||||
|
},
|
||||||
|
enterprise: {
|
||||||
|
type: 'string',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
isLatest: {
|
||||||
|
type: 'boolean',
|
||||||
|
},
|
||||||
|
instanceId: {
|
||||||
|
type: 'string',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
components: {},
|
||||||
|
} as const;
|
||||||
|
|
||||||
|
export type VersionSchema = FromSchema<typeof versionSchema>;
|
@ -1,73 +1,91 @@
|
|||||||
import { Request, Response } from 'express';
|
import { Request, Response } from 'express';
|
||||||
import { IUnleashServices } from '../../types/services';
|
import { IUnleashServices } from '../../types/services';
|
||||||
import { IAuthType, IUIConfig, IUnleashConfig } from '../../types/option';
|
import { IAuthType, IUnleashConfig } from '../../types/option';
|
||||||
import version from '../../util/version';
|
import version from '../../util/version';
|
||||||
import Controller from '../controller';
|
import Controller from '../controller';
|
||||||
import VersionService, { IVersionHolder } from '../../services/version-service';
|
import VersionService from '../../services/version-service';
|
||||||
import SettingService from '../../services/setting-service';
|
import SettingService from '../../services/setting-service';
|
||||||
import {
|
import {
|
||||||
simpleAuthKey,
|
simpleAuthKey,
|
||||||
SimpleAuthSettings,
|
SimpleAuthSettings,
|
||||||
} from '../../types/settings/simple-auth-settings';
|
} from '../../types/settings/simple-auth-settings';
|
||||||
|
import { NONE } from '../../types/permissions';
|
||||||
interface IUIConfigResponse extends IUIConfig {
|
import { createResponseSchema } from '../../openapi';
|
||||||
version: string;
|
import {
|
||||||
unleashUrl: string;
|
uiConfigSchema,
|
||||||
baseUriPath: string;
|
UiConfigSchema,
|
||||||
authenticationType?: IAuthType;
|
} from '../../openapi/spec/ui-config-schema';
|
||||||
versionInfo: IVersionHolder;
|
import { OpenApiService } from '../../services/openapi-service';
|
||||||
disablePasswordAuth: boolean;
|
|
||||||
segmentValuesLimit: number;
|
|
||||||
strategySegmentsLimit: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
class ConfigController extends Controller {
|
class ConfigController extends Controller {
|
||||||
private versionService: VersionService;
|
private versionService: VersionService;
|
||||||
|
|
||||||
private settingService: SettingService;
|
private settingService: SettingService;
|
||||||
|
|
||||||
private uiConfig: Omit<
|
private readonly openApiService: OpenApiService;
|
||||||
IUIConfigResponse,
|
|
||||||
'versionInfo' | 'disablePasswordAuth'
|
|
||||||
>;
|
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
config: IUnleashConfig,
|
config: IUnleashConfig,
|
||||||
{
|
{
|
||||||
versionService,
|
versionService,
|
||||||
settingService,
|
settingService,
|
||||||
}: Pick<IUnleashServices, 'versionService' | 'settingService'>,
|
openApiService,
|
||||||
|
}: Pick<
|
||||||
|
IUnleashServices,
|
||||||
|
'versionService' | 'settingService' | 'openApiService'
|
||||||
|
>,
|
||||||
) {
|
) {
|
||||||
super(config);
|
super(config);
|
||||||
this.versionService = versionService;
|
this.versionService = versionService;
|
||||||
this.settingService = settingService;
|
this.settingService = settingService;
|
||||||
const authenticationType =
|
this.openApiService = openApiService;
|
||||||
config.authentication && config.authentication.type;
|
|
||||||
this.uiConfig = {
|
this.route({
|
||||||
...config.ui,
|
method: 'get',
|
||||||
version,
|
path: '',
|
||||||
unleashUrl: config.server.unleashUrl,
|
handler: this.getUIConfig,
|
||||||
baseUriPath: config.server.baseUriPath,
|
permission: NONE,
|
||||||
authenticationType,
|
middleware: [
|
||||||
segmentValuesLimit: config.segmentValuesLimit,
|
openApiService.validPath({
|
||||||
strategySegmentsLimit: config.strategySegmentsLimit,
|
tags: ['admin'],
|
||||||
};
|
operationId: 'getUIConfig',
|
||||||
this.get('/', this.getUIConfig);
|
responses: {
|
||||||
|
200: createResponseSchema('uiConfigSchema'),
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async getUIConfig(
|
async getUIConfig(
|
||||||
req: Request,
|
req: Request,
|
||||||
res: Response<IUIConfigResponse>,
|
res: Response<UiConfigSchema>,
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
const config = this.uiConfig;
|
|
||||||
const simpleAuthSettings =
|
const simpleAuthSettings =
|
||||||
await this.settingService.get<SimpleAuthSettings>(simpleAuthKey);
|
await this.settingService.get<SimpleAuthSettings>(simpleAuthKey);
|
||||||
|
|
||||||
const versionInfo = this.versionService.getVersionInfo();
|
|
||||||
const disablePasswordAuth =
|
const disablePasswordAuth =
|
||||||
simpleAuthSettings?.disabled ||
|
simpleAuthSettings?.disabled ||
|
||||||
this.config.authentication.type == IAuthType.NONE;
|
this.config.authentication.type == IAuthType.NONE;
|
||||||
res.json({ ...config, versionInfo, disablePasswordAuth });
|
|
||||||
|
const response: UiConfigSchema = {
|
||||||
|
...this.config.ui,
|
||||||
|
version,
|
||||||
|
unleashUrl: this.config.server.unleashUrl,
|
||||||
|
baseUriPath: this.config.server.baseUriPath,
|
||||||
|
authenticationType: this.config.authentication?.type,
|
||||||
|
segmentValuesLimit: this.config.segmentValuesLimit,
|
||||||
|
strategySegmentsLimit: this.config.strategySegmentsLimit,
|
||||||
|
versionInfo: this.versionService.getVersionInfo(),
|
||||||
|
disablePasswordAuth,
|
||||||
|
};
|
||||||
|
|
||||||
|
this.openApiService.respondWithValidation(
|
||||||
|
200,
|
||||||
|
res,
|
||||||
|
uiConfigSchema.$id,
|
||||||
|
response,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
export default ConfigController;
|
export default ConfigController;
|
||||||
|
@ -147,6 +147,7 @@ export interface IUIConfig {
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ICspDomainOptions {
|
export interface ICspDomainOptions {
|
||||||
defaultSrc?: string[];
|
defaultSrc?: string[];
|
||||||
fontSrc?: string[];
|
fontSrc?: string[];
|
||||||
|
@ -455,6 +455,71 @@ Object {
|
|||||||
],
|
],
|
||||||
"type": "object",
|
"type": "object",
|
||||||
},
|
},
|
||||||
|
"uiConfigSchema": Object {
|
||||||
|
"additionalProperties": false,
|
||||||
|
"properties": Object {
|
||||||
|
"authenticationType": Object {
|
||||||
|
"enum": Array [
|
||||||
|
"open-source",
|
||||||
|
"demo",
|
||||||
|
"enterprise",
|
||||||
|
"hosted",
|
||||||
|
"custom",
|
||||||
|
"none",
|
||||||
|
],
|
||||||
|
"type": "string",
|
||||||
|
},
|
||||||
|
"baseUriPath": Object {
|
||||||
|
"type": "string",
|
||||||
|
},
|
||||||
|
"disablePasswordAuth": Object {
|
||||||
|
"type": "boolean",
|
||||||
|
},
|
||||||
|
"flags": Object {
|
||||||
|
"additionalProperties": Object {
|
||||||
|
"type": "boolean",
|
||||||
|
},
|
||||||
|
"type": "object",
|
||||||
|
},
|
||||||
|
"links": Object {
|
||||||
|
"items": Object {
|
||||||
|
"type": "object",
|
||||||
|
},
|
||||||
|
"type": "array",
|
||||||
|
},
|
||||||
|
"name": Object {
|
||||||
|
"type": "string",
|
||||||
|
},
|
||||||
|
"segmentValuesLimit": Object {
|
||||||
|
"type": "number",
|
||||||
|
},
|
||||||
|
"slogan": Object {
|
||||||
|
"type": "string",
|
||||||
|
},
|
||||||
|
"strategySegmentsLimit": Object {
|
||||||
|
"type": "number",
|
||||||
|
},
|
||||||
|
"unleashUrl": Object {
|
||||||
|
"type": "string",
|
||||||
|
},
|
||||||
|
"version": Object {
|
||||||
|
"type": "string",
|
||||||
|
},
|
||||||
|
"versionInfo": Object {
|
||||||
|
"$ref": "#/components/schemas/versionSchema",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"required": Array [
|
||||||
|
"version",
|
||||||
|
"unleashUrl",
|
||||||
|
"baseUriPath",
|
||||||
|
"versionInfo",
|
||||||
|
"disablePasswordAuth",
|
||||||
|
"segmentValuesLimit",
|
||||||
|
"strategySegmentsLimit",
|
||||||
|
],
|
||||||
|
"type": "object",
|
||||||
|
},
|
||||||
"updateFeatureSchema": Object {
|
"updateFeatureSchema": Object {
|
||||||
"properties": Object {
|
"properties": Object {
|
||||||
"archived": Object {
|
"archived": Object {
|
||||||
@ -567,6 +632,48 @@ Object {
|
|||||||
},
|
},
|
||||||
"type": "array",
|
"type": "array",
|
||||||
},
|
},
|
||||||
|
"versionSchema": Object {
|
||||||
|
"additionalProperties": false,
|
||||||
|
"properties": Object {
|
||||||
|
"current": Object {
|
||||||
|
"additionalProperties": false,
|
||||||
|
"properties": Object {
|
||||||
|
"enterprise": Object {
|
||||||
|
"type": "string",
|
||||||
|
},
|
||||||
|
"oss": Object {
|
||||||
|
"type": "string",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"type": "object",
|
||||||
|
},
|
||||||
|
"instanceId": Object {
|
||||||
|
"type": "string",
|
||||||
|
},
|
||||||
|
"isLatest": Object {
|
||||||
|
"type": "boolean",
|
||||||
|
},
|
||||||
|
"latest": Object {
|
||||||
|
"additionalProperties": false,
|
||||||
|
"properties": Object {
|
||||||
|
"enterprise": Object {
|
||||||
|
"type": "string",
|
||||||
|
},
|
||||||
|
"oss": Object {
|
||||||
|
"type": "string",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"type": "object",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"required": Array [
|
||||||
|
"current",
|
||||||
|
"latest",
|
||||||
|
"isLatest",
|
||||||
|
"instanceId",
|
||||||
|
],
|
||||||
|
"type": "object",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
"securitySchemes": Object {
|
"securitySchemes": Object {
|
||||||
"apiKey": Object {
|
"apiKey": Object {
|
||||||
@ -1676,6 +1783,26 @@ Object {
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
"/api/admin/ui-config": Object {
|
||||||
|
"get": Object {
|
||||||
|
"operationId": "getUIConfig",
|
||||||
|
"responses": Object {
|
||||||
|
"200": Object {
|
||||||
|
"content": Object {
|
||||||
|
"application/json": Object {
|
||||||
|
"schema": Object {
|
||||||
|
"$ref": "#/components/schemas/uiConfigSchema",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"description": "uiConfigSchema",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"tags": Array [
|
||||||
|
"admin",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
"security": Array [
|
"security": Array [
|
||||||
Object {
|
Object {
|
||||||
|
Loading…
Reference in New Issue
Block a user