ForgeTotal.js 5
en

Total.js 5

Record action audit events with a native audit sink

Total.js 5 · total5@0.0.19 actionsauditsecurity Executed against Total.js 5

An action can set audit to a text template. On successful completion, the framework sends an audit record to DEF.onAudit(name, data, context). The automatic record uses the sink name actions and includes the action id. An action can also call $.audit(message, type) explicitly; this emits its own record and can carry a type such as info.

The example replaces the audit sink with an in-memory collector to inspect its contract. It records only the name, action id, message and type. The framework also prepares contextual data and serialized request data: a real sink needs an explicit policy for secrets, retention, access and failures. An audit event is not evidence that a business transaction committed; the action should call its success callback only after the intended write succeeds.

In this version the automatic audit event occurs after the successful action callback path. It does not automatically log validation failures or failed actions.

definitions/audit.js
MAIN.auditEvents = [];
DEF.onAudit = function(name, data) {
	MAIN.auditEvents.push({ sink: name || null, action: data.action, message: data.message || '', type: data.type || null });
};

NEWACTION('AuditExample|save', {
	input: '*name:String',
	audit: 'Saved the example',
	action: function($) {
		$.callback({ ok: true });
	}
});

NEWACTION('AuditExample|explicit', {
	action: function($) {
		$.audit('Explicit example event', 'info');
		$.success();
	}
});

NEWACTION('AuditExample|fail', {
	audit: 'This must not become a success event',
	action: function($) {
		$.invalid(409);
	}
});
controllers/audit.js
exports.install = function() {
	ROUTE('POST /save/ --> *AuditExample|save');
	ROUTE('POST /explicit/ --> *AuditExample|explicit');
	ROUTE('POST /fail/ --> *AuditExample|fail');
	ROUTE('GET /events/', function($) { $.json(MAIN.auditEvents); });
};