Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
879 changes: 879 additions & 0 deletions GDPR_COMPLIANCE_GUIDE.md

Large diffs are not rendered by default.

465 changes: 465 additions & 0 deletions spec/AuditLogAdapter.spec.js

Large diffs are not rendered by default.

491 changes: 491 additions & 0 deletions spec/AuditLogController.spec.js

Large diffs are not rendered by default.

246 changes: 246 additions & 0 deletions spec/AuditLogSchemas.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,246 @@
'use strict';

const fs = require('fs');
const path = require('path');

describe('Audit Logging - Schema Operations', () => {
const testLogFolder = path.join(__dirname, 'temp-audit-logs-schema');

beforeEach(async () => {
if (fs.existsSync(testLogFolder)) {
fs.rmSync(testLogFolder, { recursive: true, force: true });
}

await reconfigureServer({
auditLog: {
auditLogFolder: testLogFolder,
},
});
});

afterEach(async () => {
if (fs.existsSync(testLogFolder)) {
fs.rmSync(testLogFolder, { recursive: true, force: true });
}
});

it('should log schema creation', async () => {
const schema = {
className: 'AuditSchemaTest',
fields: {
testField: { type: 'String' },
},
};

await request({

Check failure on line 35 in spec/AuditLogSchemas.spec.js

View workflow job for this annotation

GitHub Actions / Lint

'request' is not defined
method: 'POST',
url: Parse.serverURL + '/schemas',
body: schema,
headers: {
'X-Parse-Application-Id': Parse.applicationId,
'X-Parse-Master-Key': Parse.masterKey,
},
});

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

const logFiles = fs.readdirSync(testLogFolder);
expect(logFiles.length).toBeGreaterThan(0);

const logFile = path.join(testLogFolder, logFiles[0]);
const logContent = fs.readFileSync(logFile, 'utf8');

expect(logContent).toContain('SCHEMA_MODIFY');
expect(logContent).toContain('AuditSchemaTest');
expect(logContent).toContain('create');
});

it('should log schema update', async () => {
const schema = {
className: 'AuditSchemaUpdate',
fields: {
field1: { type: 'String' },
},
};

await request({

Check failure on line 66 in spec/AuditLogSchemas.spec.js

View workflow job for this annotation

GitHub Actions / Lint

'request' is not defined
method: 'POST',
url: Parse.serverURL + '/schemas',
body: schema,
headers: {
'X-Parse-Application-Id': Parse.applicationId,
'X-Parse-Master-Key': Parse.masterKey,
},
});

await new Promise(resolve => setTimeout(resolve, 200));
const logFiles1 = fs.readdirSync(testLogFolder);
if (logFiles1.length > 0) {
fs.unlinkSync(path.join(testLogFolder, logFiles1[0]));
}

await request({

Check failure on line 82 in spec/AuditLogSchemas.spec.js

View workflow job for this annotation

GitHub Actions / Lint

'request' is not defined
method: 'PUT',
url: Parse.serverURL + '/schemas/AuditSchemaUpdate',
body: {
fields: {
field2: { type: 'Number' },
},
},
headers: {
'X-Parse-Application-Id': Parse.applicationId,
'X-Parse-Master-Key': Parse.masterKey,
},
});

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

const logFiles = fs.readdirSync(testLogFolder);
expect(logFiles.length).toBeGreaterThan(0);

const logFile = path.join(testLogFolder, logFiles[0]);
const logContent = fs.readFileSync(logFile, 'utf8');

expect(logContent).toContain('SCHEMA_MODIFY');
expect(logContent).toContain('AuditSchemaUpdate');
expect(logContent).toContain('update');
});

it('should log schema deletion', async () => {
const schema = {
className: 'AuditSchemaDelete',
fields: {
field1: { type: 'String' },
},
};

await request({

Check failure on line 117 in spec/AuditLogSchemas.spec.js

View workflow job for this annotation

GitHub Actions / Lint

'request' is not defined
method: 'POST',
url: Parse.serverURL + '/schemas',
body: schema,
headers: {
'X-Parse-Application-Id': Parse.applicationId,
'X-Parse-Master-Key': Parse.masterKey,
},
});

await new Promise(resolve => setTimeout(resolve, 200));
const logFiles1 = fs.readdirSync(testLogFolder);
if (logFiles1.length > 0) {
fs.unlinkSync(path.join(testLogFolder, logFiles1[0]));
}

await request({

Check failure on line 133 in spec/AuditLogSchemas.spec.js

View workflow job for this annotation

GitHub Actions / Lint

'request' is not defined
method: 'DELETE',
url: Parse.serverURL + '/schemas/AuditSchemaDelete',
headers: {
'X-Parse-Application-Id': Parse.applicationId,
'X-Parse-Master-Key': Parse.masterKey,
},
});

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

const logFiles = fs.readdirSync(testLogFolder);
expect(logFiles.length).toBeGreaterThan(0);

const logFile = path.join(testLogFolder, logFiles[0]);
const logContent = fs.readFileSync(logFile, 'utf8');

expect(logContent).toContain('SCHEMA_MODIFY');
expect(logContent).toContain('AuditSchemaDelete');
expect(logContent).toContain('delete');
});

it('should log failed schema creation', async () => {
const schema = {
className: '_InvalidClassName',
fields: {
testField: { type: 'String' },
},
};

try {
await request({

Check failure on line 164 in spec/AuditLogSchemas.spec.js

View workflow job for this annotation

GitHub Actions / Lint

'request' is not defined
method: 'POST',
url: Parse.serverURL + '/schemas',
body: schema,
headers: {
'X-Parse-Application-Id': Parse.applicationId,
'X-Parse-Master-Key': Parse.masterKey,
},
});
} catch (error) {
// Expected to fail
}

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

const logFiles = fs.readdirSync(testLogFolder);
if (logFiles.length > 0) {
const logFile = path.join(testLogFolder, logFiles[0]);
const logContent = fs.readFileSync(logFile, 'utf8');

expect(logContent).toContain('SCHEMA_MODIFY');
expect(logContent).toContain('"success":false');
}
});

it('should capture user context in schema logs', async () => {
const schema = {
className: 'AuditSchemaUser',
fields: {
field1: { type: 'String' },
},
};

await request({

Check failure on line 197 in spec/AuditLogSchemas.spec.js

View workflow job for this annotation

GitHub Actions / Lint

'request' is not defined
method: 'POST',
url: Parse.serverURL + '/schemas',
body: schema,
headers: {
'X-Parse-Application-Id': Parse.applicationId,
'X-Parse-Master-Key': Parse.masterKey,
},
});

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

const logFiles = fs.readdirSync(testLogFolder);
const logFile = path.join(testLogFolder, logFiles[0]);
const logContent = fs.readFileSync(logFile, 'utf8');

expect(logContent).toContain('SCHEMA_MODIFY');
});

it('should log schema changes with field details', async () => {
const schema = {
className: 'AuditSchemaFields',
fields: {
stringField: { type: 'String' },
numberField: { type: 'Number' },
pointerField: { type: 'Pointer', targetClass: '_User' },
},
};

await request({

Check failure on line 226 in spec/AuditLogSchemas.spec.js

View workflow job for this annotation

GitHub Actions / Lint

'request' is not defined
method: 'POST',
url: Parse.serverURL + '/schemas',
body: schema,
headers: {
'X-Parse-Application-Id': Parse.applicationId,
'X-Parse-Master-Key': Parse.masterKey,
},
});

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

const logFiles = fs.readdirSync(testLogFolder);
const logFile = path.join(testLogFolder, logFiles[0]);
const logContent = fs.readFileSync(logFile, 'utf8');

expect(logContent).toContain('SCHEMA_MODIFY');
expect(logContent).toContain('stringField');
expect(logContent).toContain('numberField');
});
});
Loading
Loading