🔒 fix: Memory Disabled Config UI Permissions (#9522)

This commit is contained in:
Danny Avila 2025-09-09 09:14:40 -04:00 committed by GitHub
parent 79144a6365
commit 588e0c4611
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 182 additions and 9 deletions

View file

@ -7,10 +7,6 @@ import { loadDefaultInterface } from './interface';
const mockUpdateAccessPermissions = jest.fn(); const mockUpdateAccessPermissions = jest.fn();
const mockGetRoleByName = jest.fn(); const mockGetRoleByName = jest.fn();
jest.mock('~/memory', () => ({
isMemoryEnabled: jest.fn((config) => config?.enable === true),
}));
describe('updateInterfacePermissions - permissions', () => { describe('updateInterfacePermissions - permissions', () => {
beforeEach(() => { beforeEach(() => {
jest.clearAllMocks(); jest.clearAllMocks();
@ -58,6 +54,9 @@ describe('updateInterfacePermissions - permissions', () => {
[PermissionTypes.BOOKMARKS]: { [Permissions.USE]: true }, [PermissionTypes.BOOKMARKS]: { [Permissions.USE]: true },
[PermissionTypes.MEMORIES]: { [PermissionTypes.MEMORIES]: {
[Permissions.USE]: true, [Permissions.USE]: true,
[Permissions.CREATE]: true,
[Permissions.READ]: true,
[Permissions.UPDATE]: true,
[Permissions.OPT_OUT]: undefined, [Permissions.OPT_OUT]: undefined,
}, },
[PermissionTypes.MULTI_CONVO]: { [Permissions.USE]: true }, [PermissionTypes.MULTI_CONVO]: { [Permissions.USE]: true },
@ -84,6 +83,9 @@ describe('updateInterfacePermissions - permissions', () => {
[PermissionTypes.BOOKMARKS]: { [Permissions.USE]: true }, [PermissionTypes.BOOKMARKS]: { [Permissions.USE]: true },
[PermissionTypes.MEMORIES]: { [PermissionTypes.MEMORIES]: {
[Permissions.USE]: true, [Permissions.USE]: true,
[Permissions.CREATE]: true,
[Permissions.READ]: true,
[Permissions.UPDATE]: true,
[Permissions.OPT_OUT]: undefined, [Permissions.OPT_OUT]: undefined,
}, },
[PermissionTypes.MULTI_CONVO]: { [Permissions.USE]: true }, [PermissionTypes.MULTI_CONVO]: { [Permissions.USE]: true },
@ -160,6 +162,9 @@ describe('updateInterfacePermissions - permissions', () => {
[PermissionTypes.BOOKMARKS]: { [Permissions.USE]: false }, [PermissionTypes.BOOKMARKS]: { [Permissions.USE]: false },
[PermissionTypes.MEMORIES]: { [PermissionTypes.MEMORIES]: {
[Permissions.USE]: false, [Permissions.USE]: false,
[Permissions.CREATE]: true,
[Permissions.READ]: true,
[Permissions.UPDATE]: true,
[Permissions.OPT_OUT]: undefined, [Permissions.OPT_OUT]: undefined,
}, },
[PermissionTypes.MULTI_CONVO]: { [Permissions.USE]: false }, [PermissionTypes.MULTI_CONVO]: { [Permissions.USE]: false },
@ -186,6 +191,9 @@ describe('updateInterfacePermissions - permissions', () => {
[PermissionTypes.BOOKMARKS]: { [Permissions.USE]: false }, [PermissionTypes.BOOKMARKS]: { [Permissions.USE]: false },
[PermissionTypes.MEMORIES]: { [PermissionTypes.MEMORIES]: {
[Permissions.USE]: false, [Permissions.USE]: false,
[Permissions.CREATE]: true,
[Permissions.READ]: true,
[Permissions.UPDATE]: true,
[Permissions.OPT_OUT]: undefined, [Permissions.OPT_OUT]: undefined,
}, },
[PermissionTypes.MULTI_CONVO]: { [Permissions.USE]: false }, [PermissionTypes.MULTI_CONVO]: { [Permissions.USE]: false },
@ -262,6 +270,9 @@ describe('updateInterfacePermissions - permissions', () => {
[PermissionTypes.BOOKMARKS]: { [Permissions.USE]: true }, [PermissionTypes.BOOKMARKS]: { [Permissions.USE]: true },
[PermissionTypes.MEMORIES]: { [PermissionTypes.MEMORIES]: {
[Permissions.USE]: true, [Permissions.USE]: true,
[Permissions.CREATE]: true,
[Permissions.READ]: true,
[Permissions.UPDATE]: true,
[Permissions.OPT_OUT]: undefined, [Permissions.OPT_OUT]: undefined,
}, },
[PermissionTypes.MULTI_CONVO]: { [Permissions.USE]: true }, [PermissionTypes.MULTI_CONVO]: { [Permissions.USE]: true },
@ -288,6 +299,9 @@ describe('updateInterfacePermissions - permissions', () => {
[PermissionTypes.BOOKMARKS]: { [Permissions.USE]: true }, [PermissionTypes.BOOKMARKS]: { [Permissions.USE]: true },
[PermissionTypes.MEMORIES]: { [PermissionTypes.MEMORIES]: {
[Permissions.USE]: true, [Permissions.USE]: true,
[Permissions.CREATE]: true,
[Permissions.READ]: true,
[Permissions.UPDATE]: true,
[Permissions.OPT_OUT]: undefined, [Permissions.OPT_OUT]: undefined,
}, },
[PermissionTypes.MULTI_CONVO]: { [Permissions.USE]: true }, [PermissionTypes.MULTI_CONVO]: { [Permissions.USE]: true },
@ -377,6 +391,9 @@ describe('updateInterfacePermissions - permissions', () => {
[PermissionTypes.BOOKMARKS]: { [Permissions.USE]: false }, [PermissionTypes.BOOKMARKS]: { [Permissions.USE]: false },
[PermissionTypes.MEMORIES]: { [PermissionTypes.MEMORIES]: {
[Permissions.USE]: true, [Permissions.USE]: true,
[Permissions.CREATE]: true,
[Permissions.READ]: true,
[Permissions.UPDATE]: true,
[Permissions.OPT_OUT]: undefined, [Permissions.OPT_OUT]: undefined,
}, },
[PermissionTypes.MULTI_CONVO]: { [Permissions.USE]: true }, [PermissionTypes.MULTI_CONVO]: { [Permissions.USE]: true },
@ -403,6 +420,9 @@ describe('updateInterfacePermissions - permissions', () => {
[PermissionTypes.BOOKMARKS]: { [Permissions.USE]: false }, [PermissionTypes.BOOKMARKS]: { [Permissions.USE]: false },
[PermissionTypes.MEMORIES]: { [PermissionTypes.MEMORIES]: {
[Permissions.USE]: true, [Permissions.USE]: true,
[Permissions.CREATE]: true,
[Permissions.READ]: true,
[Permissions.UPDATE]: true,
[Permissions.OPT_OUT]: undefined, [Permissions.OPT_OUT]: undefined,
}, },
[PermissionTypes.MULTI_CONVO]: { [Permissions.USE]: true }, [PermissionTypes.MULTI_CONVO]: { [Permissions.USE]: true },
@ -479,6 +499,9 @@ describe('updateInterfacePermissions - permissions', () => {
[PermissionTypes.BOOKMARKS]: { [Permissions.USE]: true }, [PermissionTypes.BOOKMARKS]: { [Permissions.USE]: true },
[PermissionTypes.MEMORIES]: { [PermissionTypes.MEMORIES]: {
[Permissions.USE]: true, [Permissions.USE]: true,
[Permissions.CREATE]: true,
[Permissions.READ]: true,
[Permissions.UPDATE]: true,
[Permissions.OPT_OUT]: undefined, [Permissions.OPT_OUT]: undefined,
}, },
[PermissionTypes.MULTI_CONVO]: { [Permissions.USE]: true }, [PermissionTypes.MULTI_CONVO]: { [Permissions.USE]: true },
@ -505,6 +528,9 @@ describe('updateInterfacePermissions - permissions', () => {
[PermissionTypes.BOOKMARKS]: { [Permissions.USE]: true }, [PermissionTypes.BOOKMARKS]: { [Permissions.USE]: true },
[PermissionTypes.MEMORIES]: { [PermissionTypes.MEMORIES]: {
[Permissions.USE]: true, [Permissions.USE]: true,
[Permissions.CREATE]: true,
[Permissions.READ]: true,
[Permissions.UPDATE]: true,
[Permissions.OPT_OUT]: undefined, [Permissions.OPT_OUT]: undefined,
}, },
[PermissionTypes.MULTI_CONVO]: { [Permissions.USE]: true }, [PermissionTypes.MULTI_CONVO]: { [Permissions.USE]: true },
@ -587,6 +613,9 @@ describe('updateInterfacePermissions - permissions', () => {
[PermissionTypes.BOOKMARKS]: { [Permissions.USE]: true }, [PermissionTypes.BOOKMARKS]: { [Permissions.USE]: true },
[PermissionTypes.MEMORIES]: { [PermissionTypes.MEMORIES]: {
[Permissions.USE]: true, [Permissions.USE]: true,
[Permissions.CREATE]: true,
[Permissions.READ]: true,
[Permissions.UPDATE]: true,
[Permissions.OPT_OUT]: undefined, [Permissions.OPT_OUT]: undefined,
}, },
[PermissionTypes.MULTI_CONVO]: { [Permissions.USE]: true }, [PermissionTypes.MULTI_CONVO]: { [Permissions.USE]: true },
@ -607,6 +636,9 @@ describe('updateInterfacePermissions - permissions', () => {
[PermissionTypes.BOOKMARKS]: { [Permissions.USE]: true }, [PermissionTypes.BOOKMARKS]: { [Permissions.USE]: true },
[PermissionTypes.MEMORIES]: { [PermissionTypes.MEMORIES]: {
[Permissions.USE]: true, [Permissions.USE]: true,
[Permissions.CREATE]: true,
[Permissions.READ]: true,
[Permissions.UPDATE]: true,
[Permissions.OPT_OUT]: undefined, [Permissions.OPT_OUT]: undefined,
}, },
[PermissionTypes.MULTI_CONVO]: { [Permissions.USE]: true }, [PermissionTypes.MULTI_CONVO]: { [Permissions.USE]: true },
@ -702,6 +734,9 @@ describe('updateInterfacePermissions - permissions', () => {
// All other permissions that don't exist in the database // All other permissions that don't exist in the database
[PermissionTypes.MEMORIES]: { [PermissionTypes.MEMORIES]: {
[Permissions.USE]: true, [Permissions.USE]: true,
[Permissions.CREATE]: true,
[Permissions.READ]: true,
[Permissions.UPDATE]: true,
[Permissions.OPT_OUT]: undefined, [Permissions.OPT_OUT]: undefined,
}, },
[PermissionTypes.MULTI_CONVO]: { [Permissions.USE]: true }, [PermissionTypes.MULTI_CONVO]: { [Permissions.USE]: true },
@ -725,6 +760,9 @@ describe('updateInterfacePermissions - permissions', () => {
// All other permissions that don't exist in the database // All other permissions that don't exist in the database
[PermissionTypes.MEMORIES]: { [PermissionTypes.MEMORIES]: {
[Permissions.USE]: true, [Permissions.USE]: true,
[Permissions.CREATE]: true,
[Permissions.READ]: true,
[Permissions.UPDATE]: true,
[Permissions.OPT_OUT]: undefined, [Permissions.OPT_OUT]: undefined,
}, },
[PermissionTypes.MULTI_CONVO]: { [Permissions.USE]: true }, [PermissionTypes.MULTI_CONVO]: { [Permissions.USE]: true },
@ -926,11 +964,17 @@ describe('updateInterfacePermissions - permissions', () => {
// Check MEMORIES permissions use role defaults // Check MEMORIES permissions use role defaults
expect(userCall[1][PermissionTypes.MEMORIES]).toEqual({ expect(userCall[1][PermissionTypes.MEMORIES]).toEqual({
[Permissions.USE]: true, [Permissions.USE]: true,
[Permissions.CREATE]: true,
[Permissions.READ]: true,
[Permissions.UPDATE]: true,
[Permissions.OPT_OUT]: undefined, [Permissions.OPT_OUT]: undefined,
}); });
expect(adminCall[1][PermissionTypes.MEMORIES]).toEqual({ expect(adminCall[1][PermissionTypes.MEMORIES]).toEqual({
[Permissions.USE]: true, [Permissions.USE]: true,
[Permissions.CREATE]: true,
[Permissions.READ]: true,
[Permissions.UPDATE]: true,
[Permissions.OPT_OUT]: undefined, [Permissions.OPT_OUT]: undefined,
}); });
}); });
@ -1156,4 +1200,114 @@ describe('updateInterfacePermissions - permissions', () => {
expect(userCall[1]).toHaveProperty(PermissionTypes.AGENTS); expect(userCall[1]).toHaveProperty(PermissionTypes.AGENTS);
expect(userCall[1]).toHaveProperty(PermissionTypes.MULTI_CONVO); expect(userCall[1]).toHaveProperty(PermissionTypes.MULTI_CONVO);
}); });
it('should disable all memory permissions when memory.disabled is true', async () => {
const config = {
interface: {
// Even if memories is not explicitly set to false in interface
prompts: true,
bookmarks: true,
},
memory: {
disabled: true,
// Other memory config doesn't matter when disabled
agent: {
id: 'test-agent-id',
},
personalize: true,
} as unknown as TCustomConfig['memory'],
};
const configDefaults = {
interface: {
memories: true, // Default is true
},
} as TConfigDefaults;
const interfaceConfig = await loadDefaultInterface({ config, configDefaults });
const appConfig = { config, interfaceConfig } as unknown as AppConfig;
await updateInterfacePermissions({
appConfig,
getRoleByName: mockGetRoleByName,
updateAccessPermissions: mockUpdateAccessPermissions,
});
const expectedMemoryPermissions = {
[Permissions.USE]: false,
[Permissions.CREATE]: false,
[Permissions.READ]: false,
[Permissions.UPDATE]: false,
[Permissions.OPT_OUT]: false, // Even OPT_OUT should be false when memory is disabled
};
// Check USER role call
const userCall = mockUpdateAccessPermissions.mock.calls.find(
(call) => call[0] === SystemRoles.USER,
);
expect(userCall[1][PermissionTypes.MEMORIES]).toEqual(expectedMemoryPermissions);
// Check ADMIN role call
const adminCall = mockUpdateAccessPermissions.mock.calls.find(
(call) => call[0] === SystemRoles.ADMIN,
);
expect(adminCall[1][PermissionTypes.MEMORIES]).toEqual(expectedMemoryPermissions);
});
it('should enable memory permissions based on role defaults when memory is configured without disabled flag', async () => {
const config = {
interface: {
memories: true,
},
memory: {
// Memory is configured with an agent but not disabled
agent: {
provider: 'openai',
model: 'gpt-4',
},
personalize: true,
} as unknown as TCustomConfig['memory'],
};
const configDefaults = {
interface: {
memories: true,
},
} as TConfigDefaults;
const interfaceConfig = await loadDefaultInterface({ config, configDefaults });
const appConfig = { config, interfaceConfig } as unknown as AppConfig;
await updateInterfacePermissions({
appConfig,
getRoleByName: mockGetRoleByName,
updateAccessPermissions: mockUpdateAccessPermissions,
});
// Check USER role call - should use role defaults for non-USE permissions
const userCall = mockUpdateAccessPermissions.mock.calls.find(
(call) => call[0] === SystemRoles.USER,
);
expect(userCall[1][PermissionTypes.MEMORIES]).toEqual({
[Permissions.USE]: true,
[Permissions.CREATE]:
roleDefaults[SystemRoles.USER].permissions[PermissionTypes.MEMORIES]?.[Permissions.CREATE],
[Permissions.READ]:
roleDefaults[SystemRoles.USER].permissions[PermissionTypes.MEMORIES]?.[Permissions.READ],
[Permissions.UPDATE]:
roleDefaults[SystemRoles.USER].permissions[PermissionTypes.MEMORIES]?.[Permissions.UPDATE],
[Permissions.OPT_OUT]: true, // Should be true when personalize is enabled
});
// Check ADMIN role call
const adminCall = mockUpdateAccessPermissions.mock.calls.find(
(call) => call[0] === SystemRoles.ADMIN,
);
expect(adminCall[1][PermissionTypes.MEMORIES]).toEqual({
[Permissions.USE]: true,
[Permissions.CREATE]:
roleDefaults[SystemRoles.ADMIN].permissions[PermissionTypes.MEMORIES]?.[Permissions.CREATE],
[Permissions.READ]:
roleDefaults[SystemRoles.ADMIN].permissions[PermissionTypes.MEMORIES]?.[Permissions.READ],
[Permissions.UPDATE]:
roleDefaults[SystemRoles.ADMIN].permissions[PermissionTypes.MEMORIES]?.[Permissions.UPDATE],
[Permissions.OPT_OUT]: true, // Should be true when personalize is enabled
});
});
}); });

View file

@ -69,6 +69,8 @@ export async function updateInterfacePermissions({
const interfaceConfig = appConfig?.config?.interface; const interfaceConfig = appConfig?.config?.interface;
const memoryConfig = appConfig?.config?.memory; const memoryConfig = appConfig?.config?.memory;
const memoryEnabled = isMemoryEnabled(memoryConfig); const memoryEnabled = isMemoryEnabled(memoryConfig);
/** Check if memory is explicitly disabled */
const isMemoryExplicitlyDisabled = memoryConfig && !memoryEnabled;
/** Check if personalization is enabled (defaults to true if memory is configured and enabled) */ /** Check if personalization is enabled (defaults to true if memory is configured and enabled) */
const isPersonalizationEnabled = const isPersonalizationEnabled =
memoryConfig && memoryEnabled && memoryConfig.personalize !== false; memoryConfig && memoryEnabled && memoryConfig.personalize !== false;
@ -139,11 +141,28 @@ export async function updateInterfacePermissions({
), ),
}, },
[PermissionTypes.MEMORIES]: { [PermissionTypes.MEMORIES]: {
[Permissions.USE]: getPermissionValue( [Permissions.USE]: isMemoryExplicitlyDisabled
loadedInterface.memories, ? false
defaultPerms[PermissionTypes.MEMORIES]?.[Permissions.USE], : getPermissionValue(
defaults.memories, loadedInterface.memories,
), defaultPerms[PermissionTypes.MEMORIES]?.[Permissions.USE],
defaults.memories,
),
...(defaultPerms[PermissionTypes.MEMORIES]?.[Permissions.CREATE] !== undefined && {
[Permissions.CREATE]: isMemoryExplicitlyDisabled
? false
: defaultPerms[PermissionTypes.MEMORIES][Permissions.CREATE],
}),
...(defaultPerms[PermissionTypes.MEMORIES]?.[Permissions.READ] !== undefined && {
[Permissions.READ]: isMemoryExplicitlyDisabled
? false
: defaultPerms[PermissionTypes.MEMORIES][Permissions.READ],
}),
...(defaultPerms[PermissionTypes.MEMORIES]?.[Permissions.UPDATE] !== undefined && {
[Permissions.UPDATE]: isMemoryExplicitlyDisabled
? false
: defaultPerms[PermissionTypes.MEMORIES][Permissions.UPDATE],
}),
[Permissions.OPT_OUT]: isPersonalizationEnabled, [Permissions.OPT_OUT]: isPersonalizationEnabled,
}, },
[PermissionTypes.MULTI_CONVO]: { [PermissionTypes.MULTI_CONVO]: {