mirror of
https://github.com/danny-avila/LibreChat.git
synced 2026-10-23 10:36:09 +00:00
🛠️ fix: Normalize blank tenantId before persisting audit entries
The `recordAuditEntry` write path was treating any non-null tenantId as a
real string, so empty or whitespace-only values reached the schema validator,
failed the non-empty-string check, and silently dropped the audit row. The
read-side `tenantFilter` already treats those values as platform-level scope,
so the write path now mirrors it: blank or whitespace-only tenantId becomes
an omitted field, which matches `{ tenantId: { $exists: false } }` queries
and clears validation. Added a regression test that records two entries with
blank and whitespace tenantId and asserts both persist with the tenantId
field absent.
This commit is contained in:
parent
2bbcafecd7
commit
db0d5fda49
2 changed files with 23 additions and 1 deletions
|
|
@ -69,6 +69,18 @@ describe('auditLog methods', () => {
|
|||
const raw = await AuditLog.collection.findOne({});
|
||||
expect(raw && Object.prototype.hasOwnProperty.call(raw, 'tenantId')).toBe(false);
|
||||
});
|
||||
|
||||
it('treats blank and whitespace-only tenantId as platform-level (no silent drop)', async () => {
|
||||
const blank = await methods.recordAuditEntry(baseInput({ tenantId: '' }));
|
||||
const whitespace = await methods.recordAuditEntry(baseInput({ tenantId: ' ' }));
|
||||
expect(blank).not.toBeNull();
|
||||
expect(whitespace).not.toBeNull();
|
||||
const rows = await AuditLog.collection.find({}).toArray();
|
||||
expect(rows).toHaveLength(2);
|
||||
for (const row of rows) {
|
||||
expect(Object.prototype.hasOwnProperty.call(row, 'tenantId')).toBe(false);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe('listAuditLogPage', () => {
|
||||
|
|
|
|||
|
|
@ -120,6 +120,16 @@ function clampLimit(limit?: number): number {
|
|||
export function createAuditLogMethods(mongoose: typeof import('mongoose')): AuditLogMethods {
|
||||
async function recordAuditEntry(input: RecordAuditEntryInput): Promise<IAuditLog | null> {
|
||||
const AuditLog = mongoose.models.AuditLog as Model<IAuditLog>;
|
||||
/**
|
||||
* Match the read-side `tenantFilter` convention: blank or whitespace-only
|
||||
* tenant IDs are platform-level scope and the field must be omitted
|
||||
* entirely (so the row matches `{ tenantId: { $exists: false } }` queries
|
||||
* and satisfies the non-empty-string validator on the schema).
|
||||
*/
|
||||
const normalizedTenantId =
|
||||
typeof input.tenantId === 'string' && input.tenantId.trim().length > 0
|
||||
? input.tenantId
|
||||
: undefined;
|
||||
try {
|
||||
const doc = await AuditLog.create({
|
||||
action: input.action,
|
||||
|
|
@ -129,7 +139,7 @@ export function createAuditLogMethods(mongoose: typeof import('mongoose')): Audi
|
|||
targetPrincipalId: input.targetPrincipalId,
|
||||
targetName: input.targetName,
|
||||
capability: input.capability,
|
||||
...(input.tenantId != null && { tenantId: input.tenantId }),
|
||||
...(normalizedTenantId !== undefined && { tenantId: normalizedTenantId }),
|
||||
});
|
||||
return doc;
|
||||
} catch (err) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue