Skip to content

Commit 30cb136

Browse files
committed
coderabbit feedback
1 parent 83f5674 commit 30cb136

File tree

8 files changed

+57
-29
lines changed

8 files changed

+57
-29
lines changed

spec/AuditLogController.spec.js

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -482,10 +482,4 @@ describe('AuditLogController', () => {
482482
expect(controller.isEnabled()).toBe(false);
483483
});
484484
});
485-
486-
describe('expectedAdapterType', () => {
487-
it('should return AuditLogAdapter', () => {
488-
expect(controller.expectedAdapterType()).toBe(AuditLogAdapter);
489-
});
490-
});
491485
});

spec/Auth.spec.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -320,8 +320,11 @@ describe('Audit Logging - User Authentication', () => {
320320

321321
try {
322322
await Parse.User.logIn('audituser2', 'wrongpassword');
323+
fail('Expected login to fail with wrong password');
323324
} catch (error) {
324-
// Expected error
325+
// Verify this is the expected authentication failure
326+
expect(error.code).toBe(Parse.Error.OBJECT_NOT_FOUND);
327+
expect(error.message).toContain('Invalid username/password');
325328
}
326329

327330
await new Promise(resolve => setTimeout(resolve, 200));

spec/ParseObject.spec.js

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2371,8 +2371,6 @@ describe('Audit Logging - CRUD Operations', () => {
23712371
});
23722372

23732373
it('should not log internal master key operations without user', async () => {
2374-
Parse.Cloud.useMasterKey();
2375-
23762374
const TestClass = Parse.Object.extend('AuditCRUDInternal');
23772375
const obj = new TestClass();
23782376
obj.set('name', 'internal');

src/Adapters/Logger/AuditLogger.js

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,25 @@ export function configureAuditLogger({
6363
maxFiles,
6464
} = {}) {
6565
if (!auditLogFolder) {
66-
// Audit logging disabled
66+
// Audit logging disabled - close and remove any existing transports
67+
try {
68+
if (auditLogger.transports && auditLogger.transports.length > 0) {
69+
// Close all transports
70+
auditLogger.transports.forEach(transport => {
71+
try {
72+
if (transport.close) {
73+
transport.close();
74+
}
75+
} catch (err) {
76+
// Ignore errors during transport cleanup
77+
}
78+
});
79+
// Clear all transports
80+
auditLogger.clear();
81+
}
82+
} catch (err) {
83+
// Ignore errors during cleanup
84+
}
6785
return;
6886
}
6987

@@ -77,6 +95,23 @@ export function configureAuditLogger({
7795
} catch (e) {
7896
// eslint-disable-next-line no-console
7997
console.error('Failed to create audit log folder:', e);
98+
// Clean up existing transports since audit logging cannot be enabled
99+
try {
100+
if (auditLogger.transports && auditLogger.transports.length > 0) {
101+
auditLogger.transports.forEach(transport => {
102+
try {
103+
if (transport.close) {
104+
transport.close();
105+
}
106+
} catch (err) {
107+
// Ignore errors during transport cleanup
108+
}
109+
});
110+
auditLogger.clear();
111+
}
112+
} catch (err) {
113+
// Ignore errors during cleanup
114+
}
80115
return;
81116
}
82117

src/Controllers/AuditLogController.js

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
1-
import AdaptableController from './AdaptableController';
21
import { AuditLogAdapter } from '../Adapters/Logger/AuditLogAdapter';
32

43
/**
54
* AuditLogController
65
* Controller for managing GDPR-compliant audit logging
76
*/
8-
export class AuditLogController extends AdaptableController {
7+
export class AuditLogController {
98
constructor(adapter, appId, options = {}) {
10-
super(adapter, appId, options);
119
this.adapter = adapter;
10+
this.appId = appId;
11+
this.options = options;
1212
}
1313

1414
/**
@@ -311,11 +311,7 @@ export class AuditLogController extends AdaptableController {
311311
* @returns {boolean} True if enabled
312312
*/
313313
isEnabled() {
314-
return this.adapter && this.adapter.isEnabled();
315-
}
316-
317-
expectedAdapterType() {
318-
return AuditLogAdapter;
314+
return !!(this.adapter && this.adapter.isEnabled());
319315
}
320316
}
321317

src/RestQuery.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -978,8 +978,7 @@ _UnsafeRestQuery.prototype.logAuditDataView = function () {
978978
});
979979
} catch (error) {
980980
// Don't fail the query if audit logging fails
981-
// eslint-disable-next-line no-console
982-
console.error('Audit logging error:', error);
981+
this.config.loggerController.error('Audit logging error in RestQuery', { error });
983982
}
984983

985984
return Promise.resolve();

src/RestWrite.js

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1803,7 +1803,9 @@ RestWrite.prototype.logAuditDataWrite = function () {
18031803
return Promise.resolve();
18041804
}
18051805

1806-
if ((this.auth.isMaster || this.auth.isMaintenance) && !this.auth.user) {
1806+
// Skip only master key operations without a user context
1807+
// Maintenance mode operations should still be audited
1808+
if (this.auth.isMaster && !this.auth.user) {
18071809
return Promise.resolve();
18081810
}
18091811

@@ -1815,8 +1817,10 @@ RestWrite.prototype.logAuditDataWrite = function () {
18151817
const isCreate = !this.query;
18161818
const isUpdate = !!this.query;
18171819

1818-
const aclModified = this.originalData && this.originalData.ACL && this.data.ACL &&
1819-
JSON.stringify(this.originalData.ACL) !== JSON.stringify(this.data.ACL);
1820+
// Check if ACL was modified, including cases where ACL was added or removed
1821+
const originalACL = this.originalData?.ACL ?? null;
1822+
const newACL = this.data?.ACL ?? null;
1823+
const aclModified = isUpdate && JSON.stringify(originalACL) !== JSON.stringify(newACL);
18201824

18211825
try {
18221826
if (isCreate) {
@@ -1849,15 +1853,14 @@ RestWrite.prototype.logAuditDataWrite = function () {
18491853
req: { config: this.config },
18501854
className: this.className,
18511855
objectId: objectId,
1852-
oldACL: this.originalData.ACL,
1853-
newACL: this.data.ACL,
1856+
oldACL: originalACL,
1857+
newACL: newACL,
18541858
success: true,
18551859
});
18561860
}
18571861
} catch (error) {
18581862
// Don't fail the write if audit logging fails
1859-
// eslint-disable-next-line no-console
1860-
console.error('Audit logging error:', error);
1863+
this.config.loggerController.error('Audit logging error in RestWrite', { error });
18611864
}
18621865

18631866
return Promise.resolve();

src/Routers/UsersRouter.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -317,7 +317,7 @@ export class UsersRouter extends ClassesRouter {
317317

318318
if (req.config.auditLogController) {
319319
req.config.auditLogController.logUserLogin({
320-
auth: { ...req.auth, user: afterLoginUser, sessionToken: user.sessionToken },
320+
auth: { ...req.auth, user: afterLoginUser, sessionToken: user.sessionToken ? '***masked***' : undefined },
321321
req,
322322
username: user.username || user.email,
323323
success: true,
@@ -393,7 +393,7 @@ export class UsersRouter extends ClassesRouter {
393393
if (req.config.auditLogController) {
394394
const afterLoginUser = Parse.User.fromJSON(Object.assign({ className: '_User' }, user));
395395
req.config.auditLogController.logUserLogin({
396-
auth: { ...req.auth, user: afterLoginUser, sessionToken: user.sessionToken },
396+
auth: { ...req.auth, user: afterLoginUser, sessionToken: user.sessionToken ? '***masked***' : undefined },
397397
req,
398398
username: user.username || user.email || userId,
399399
success: true,

0 commit comments

Comments
 (0)