forked from boos/BoosAPI
fix(settings): persist model allowlist as JSON array
This commit is contained in:
@@ -81,6 +81,8 @@ describe('settings and auth events', () => {
|
|||||||
(config as any).telegramChatId = '';
|
(config as any).telegramChatId = '';
|
||||||
(config as any).telegramUseSystemProxy = false;
|
(config as any).telegramUseSystemProxy = false;
|
||||||
(config as any).telegramMessageThreadId = '';
|
(config as any).telegramMessageThreadId = '';
|
||||||
|
config.globalBlockedBrands = [];
|
||||||
|
config.globalAllowedModels = [];
|
||||||
});
|
});
|
||||||
|
|
||||||
afterAll(async () => {
|
afterAll(async () => {
|
||||||
@@ -745,6 +747,32 @@ describe('settings and auth events', () => {
|
|||||||
expect(runtime.proxyEmptyContentFailEnabled).toBe(true);
|
expect(runtime.proxyEmptyContentFailEnabled).toBe(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('persists global model and brand filters as JSON arrays', async () => {
|
||||||
|
const updateResponse = await app.inject({
|
||||||
|
method: 'PUT',
|
||||||
|
url: '/api/settings/runtime',
|
||||||
|
payload: {
|
||||||
|
globalAllowedModels: ['model-alpha', ' model-beta ', 'model-alpha', 'model-gamma'],
|
||||||
|
globalBlockedBrands: ['Codex', ' Codex ', 'Gemini'],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(updateResponse.statusCode).toBe(200);
|
||||||
|
const updated = updateResponse.json() as {
|
||||||
|
globalAllowedModels?: string[];
|
||||||
|
globalBlockedBrands?: string[];
|
||||||
|
};
|
||||||
|
expect(updated.globalAllowedModels).toEqual(['model-alpha', 'model-beta', 'model-gamma']);
|
||||||
|
expect(updated.globalBlockedBrands).toEqual(['Codex', 'Gemini']);
|
||||||
|
|
||||||
|
const rows = await db.select().from(schema.settings).all();
|
||||||
|
const settingsMap = new Map(rows.map((row) => [row.key, row.value]));
|
||||||
|
expect(settingsMap.get('global_allowed_models')).toBe(JSON.stringify(['model-alpha', 'model-beta', 'model-gamma']));
|
||||||
|
expect(JSON.parse(settingsMap.get('global_allowed_models') || 'null')).toEqual(['model-alpha', 'model-beta', 'model-gamma']);
|
||||||
|
expect(settingsMap.get('global_blocked_brands')).toBe(JSON.stringify(['Codex', 'Gemini']));
|
||||||
|
expect(JSON.parse(settingsMap.get('global_blocked_brands') || 'null')).toEqual(['Codex', 'Gemini']);
|
||||||
|
});
|
||||||
|
|
||||||
it('persists and returns log cleanup settings from runtime settings', async () => {
|
it('persists and returns log cleanup settings from runtime settings', async () => {
|
||||||
const updateResponse = await app.inject({
|
const updateResponse = await app.inject({
|
||||||
method: 'PUT',
|
method: 'PUT',
|
||||||
|
|||||||
@@ -1425,7 +1425,7 @@ export async function settingsRoutes(app: FastifyInstance) {
|
|||||||
changedLabels.push('全局品牌屏蔽');
|
changedLabels.push('全局品牌屏蔽');
|
||||||
}
|
}
|
||||||
config.globalBlockedBrands = uniqueBrands;
|
config.globalBlockedBrands = uniqueBrands;
|
||||||
upsertSetting('global_blocked_brands', JSON.stringify(uniqueBrands));
|
upsertSetting('global_blocked_brands', uniqueBrands);
|
||||||
if (prev !== next) {
|
if (prev !== next) {
|
||||||
startBackgroundTask(
|
startBackgroundTask(
|
||||||
{
|
{
|
||||||
@@ -1450,7 +1450,7 @@ export async function settingsRoutes(app: FastifyInstance) {
|
|||||||
changedLabels.push('全局模型白名单');
|
changedLabels.push('全局模型白名单');
|
||||||
}
|
}
|
||||||
config.globalAllowedModels = uniqueModels;
|
config.globalAllowedModels = uniqueModels;
|
||||||
upsertSetting('global_allowed_models', JSON.stringify(uniqueModels));
|
upsertSetting('global_allowed_models', uniqueModels);
|
||||||
if (prev !== next) {
|
if (prev !== next) {
|
||||||
startBackgroundTask(
|
startBackgroundTask(
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -44,4 +44,14 @@ describe('applyRuntimeSettings', () => {
|
|||||||
|
|
||||||
expect(config.smtpPort).toBe(587);
|
expect(config.smtpPort).toBe(587);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('hydrates legacy double-encoded global model allowlist values', () => {
|
||||||
|
config.globalAllowedModels = [];
|
||||||
|
|
||||||
|
applyRuntimeSettings(new Map([
|
||||||
|
['global_allowed_models', JSON.stringify(JSON.stringify(['model-alpha', ' model-beta ', 'model-gamma']))],
|
||||||
|
]));
|
||||||
|
|
||||||
|
expect(config.globalAllowedModels).toEqual(['model-alpha', 'model-beta', 'model-gamma']);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -22,6 +22,14 @@ function toStringList(value: unknown): string[] {
|
|||||||
.filter((item) => item.length > 0);
|
.filter((item) => item.length > 0);
|
||||||
}
|
}
|
||||||
if (typeof value === 'string') {
|
if (typeof value === 'string') {
|
||||||
|
try {
|
||||||
|
const parsed = JSON.parse(value);
|
||||||
|
if (Array.isArray(parsed)) {
|
||||||
|
return toStringList(parsed);
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
// Fall back to comma splitting for legacy plain-string lists.
|
||||||
|
}
|
||||||
return value
|
return value
|
||||||
.split(',')
|
.split(',')
|
||||||
.map((item) => item.trim())
|
.map((item) => item.trim())
|
||||||
|
|||||||
Reference in New Issue
Block a user