diff --git a/README.md b/README.md index 4428c75..7cd80a6 100644 --- a/README.md +++ b/README.md @@ -1,21 +1,25 @@ -# adonis-auditable +# adonis-audit Audit models in AdonisJS +## DISCLAIMER + +This is just a release for using it through NPM. Not claiming any rights over the original code developed. + ## How to use Install npm module: ```bash -$ adonis install adonis-auditable +$ adonis install adonis-audit ``` ## Register provider -Once you have installed adonis-auditable, make sure to register the provider inside `start/app.js` in order to make use of it. +Once you have installed adonis-audit, make sure to register the provider inside `start/app.js` in order to make use of it. ```js const providers = [ - 'adonis-auditable/providers/AuditableProvider' + 'adonis-audit/providers/AuditProvider' ] ``` diff --git a/instructions.js b/instructions.js index c5b2f3e..9002967 100644 --- a/instructions.js +++ b/instructions.js @@ -1,35 +1,35 @@ -'use strict' +"use strict"; -const path = require('path') +const path = require("path"); async function copyAuditMigration (cli) { try { - const migrationsFile = cli.helpers.migrationsPath(`${new Date().getTime()}_audit.js`) + const migrationsFile = cli.helpers.migrationsPath( + `${new Date().getTime()}_audit.js`); await cli.copy( - path.join(__dirname, 'templates', 'AuditSchema.js'), - path.join(migrationsFile) - ) - cli.command.completed('create', migrationsFile.replace(cli.helpers.appRoot(), '').replace(path.sep, '')) - } - catch (error) { - console.log(error) + path.join(__dirname, "templates", "AuditSchema.js"), + path.join(migrationsFile), + ); + cli.command.completed("create", + migrationsFile.replace(cli.helpers.appRoot(), "").replace(path.sep, "")); + } catch (error) { + console.log(error); } } async function copyAuditModel (cli) { try { await cli.copy( - path.join(__dirname, 'templates', 'Audit.js'), - path.join(cli.appDir, 'Models/Audit.js') - ) - cli.command.completed('create', 'Models/Audit.js') - } - catch (error) { - console.log(error) + path.join(__dirname, "templates", "Audit.js"), + path.join(cli.appDir, "Models/Audit.js"), + ); + cli.command.completed("create", "Models/Audit.js"); + } catch (error) { + console.log(error); } } module.exports = async (cli) => { - await copyAuditModel(cli) - await copyAuditMigration(cli) -} + await copyAuditModel(cli); + await copyAuditMigration(cli); +}; diff --git a/instructions.md b/instructions.md index 0372750..1e409ba 100644 --- a/instructions.md +++ b/instructions.md @@ -4,7 +4,7 @@ Start by registering the provider inside `start/app.js` file. ```js const providers = [ - 'adonis-auditable/providers/AuditableProvider' + 'adonis-audit/providers/AuditProvider' ] ``` diff --git a/package.json b/package.json index b32b0ae..4844238 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "name": "adonis-auditable", + "name": "adonis-audit", "version": "2.0.1", "description": "Audit AdonisJS models", "main": " ", @@ -8,7 +8,7 @@ }, "repository": { "type": "git", - "url": "git+https://github.com/simontong/adonis-auditable.git" + "url": "git+https://github.com/ahtinurme/adonis-audit.git" }, "keywords": [ "adonis", @@ -18,9 +18,9 @@ "author": "Simon Tong ", "license": "MIT", "bugs": { - "url": "https://github.com/simontong/adonis-auditable/issues" + "url": "https://github.com/ahtinurme/adonis-audit/issues" }, - "homepage": "https://github.com/simontong/adonis-auditable#readme", + "homepage": "https://github.com/ahtinurme/adonis-audit#readme", "dependencies": { "lodash": "^4.17.4" } diff --git a/providers/AuditProvider.js b/providers/AuditProvider.js new file mode 100644 index 0000000..b89bc7b --- /dev/null +++ b/providers/AuditProvider.js @@ -0,0 +1,24 @@ +const { ServiceProvider } = require("@adonisjs/fold"); + +class AuditProvider extends ServiceProvider { + register () { + this.app.singleton("Adonis/Traits/Auditable", () => { + // const Config = this.app.use('Adonis/Src/Config') + const Auditable = require("../src/Traits/Auditable"); + return new Auditable(); + }); + this.app.alias("Adonis/Traits/Auditable", "Auditable"); + } + + boot () { + const Context = this.app.use("Adonis/Src/HttpContext"); + const Auditable = this.app.use("Auditable"); + + // add ctx to datagrid + Context.onReady(ctx => { + Auditable.ctx = ctx; + }); + } +} + +module.exports = AuditProvider; diff --git a/providers/AuditableProvider.js b/providers/AuditableProvider.js deleted file mode 100644 index d5ed6d7..0000000 --- a/providers/AuditableProvider.js +++ /dev/null @@ -1,24 +0,0 @@ -const {ServiceProvider} = require('@adonisjs/fold') - -class AuditableProvider extends ServiceProvider { - register () { - this.app.singleton('Adonis/Traits/Auditable', () => { - // const Config = this.app.use('Adonis/Src/Config') - const Auditable = require('../src/Traits/Auditable') - return new Auditable() - }) - this.app.alias('Adonis/Traits/Auditable', 'Auditable') - } - - boot () { - const Context = this.app.use('Adonis/Src/HttpContext') - const Auditable = this.app.use('Auditable') - - // add ctx to datagrid - Context.onReady(ctx => { - Auditable.ctx = ctx - }) - } -} - -module.exports = AuditableProvider diff --git a/src/Traits/Auditable.js b/src/Traits/Auditable.js index 15df731..715a854 100644 --- a/src/Traits/Auditable.js +++ b/src/Traits/Auditable.js @@ -1,25 +1,25 @@ -'use strict' +"use strict"; -const _ = require('lodash') -const Audit = use('App/Models/Audit') +const _ = require("lodash"); +const Audit = use("App/Models/Audit"); class Auditable { register (Model) { // create methods - const self = this + const self = this; Model.audit = function () { return { - create: createWithAudit(self.ctx).bind(this) - } - } + create: createWithAudit(self.ctx).bind(this), + }; + }; // update/delete methods Model.prototype.audit = function () { return { update: updateWithAudit(self.ctx).bind(this), - delete: deleteWithAudit(self.ctx).bind(this) - } - } + delete: deleteWithAudit(self.ctx).bind(this), + }; + }; } } @@ -30,20 +30,21 @@ class Auditable { * @param request * @returns {*} */ -function createWithAudit ({request, auth}) { +function createWithAudit ({ request, auth }) { return async function (data) { - const model = await this.create(data) - const newModel = (await this.find(model.primaryKeyValue)) - const auditable = newModel.constructor.name - const auditableId = newModel.id - const newData = newModel.$attributes - const event = Audit.events.CREATE + const model = await this.create(data); + const newModel = (await this.find(model.primaryKeyValue)); + const auditable = newModel.constructor.name; + const auditableId = newModel.id; + const newData = newModel.$attributes; + const event = Audit.events.CREATE; // save audit - await createAudit(event, {request, auth}, auditable, auditableId, null, newData) + await createAudit(event, { request, auth }, auditable, auditableId, null, + newData); - return model - } + return model; + }; } /** @@ -53,33 +54,34 @@ function createWithAudit ({request, auth}) { * @param request * @returns {*} */ -function updateWithAudit ({request, auth}) { - return async function (data, ignoreDiff = ['updated_at']) { - const auditable = this.constructor.name - const auditableId = this.id - const oldData = this.$originalAttributes - this.merge(data) - const result = await this.save() - const newModel = (await this.constructor.find(this.primaryKeyValue)) - const newData = newModel.$attributes +function updateWithAudit ({ request, auth }) { + return async function (data, ignoreDiff = ["updated_at"]) { + const auditable = this.constructor.name; + const auditableId = this.id; + const oldData = this.$originalAttributes; + this.merge(data); + const result = await this.save(); + const newModel = (await this.constructor.find(this.primaryKeyValue)); + const newData = newModel.$attributes; // if new and old are equal then don't bother updating const isEqual = _.isEqual( _.omit(newData, ignoreDiff), - _.omit(oldData, ignoreDiff) - ) + _.omit(oldData, ignoreDiff), + ); if (isEqual) { - return result + return result; } // update / patch are shared - const event = Audit.events.UPDATE + const event = Audit.events.UPDATE; // save audit - await createAudit(event, {request, auth}, auditable, auditableId, oldData, newData) + await createAudit(event, { request, auth }, auditable, auditableId, oldData, + newData); - return result - } + return result; + }; } /** @@ -89,18 +91,19 @@ function updateWithAudit ({request, auth}) { * @param request * @returns {*} */ -function deleteWithAudit ({request, auth}) { +function deleteWithAudit ({ request, auth }) { return async function () { - const auditable = this.constructor.name - const auditableId = this.id - const oldData = this.$originalAttributes - const result = await this.delete() + const auditable = this.constructor.name; + const auditableId = this.id; + const oldData = this.$originalAttributes; + const result = await this.delete(); // save audit - await createAudit(Audit.events.DELETE, {request, auth}, auditable, auditableId, oldData) + await createAudit(Audit.events.DELETE, { request, auth }, auditable, + auditableId, oldData); - return result - } + return result; + }; } /** @@ -115,16 +118,17 @@ function deleteWithAudit ({request, auth}) { * @param request * @returns {Promise} */ -async function createAudit (event, {request, auth}, auditable, auditableId, oldData, newData) { +async function createAudit ( + event, { request, auth }, auditable, auditableId, oldData, newData) { // check request was passed if (!request) { - throw new Error('Request param is empty') + throw new Error("Request param is empty"); } // get user data to store - const userId = _.get(auth, 'user.id', null) - const url = request.originalUrl() - const ip = request.ip() + const userId = _.get(auth, "user.id", null); + const url = request.originalUrl(); + const ip = request.ip(); // save audit await Audit.create({ @@ -136,7 +140,7 @@ async function createAudit (event, {request, auth}, auditable, auditableId, oldD ip, old_data: oldData, new_data: newData, - }) + }); } -module.exports = Auditable +module.exports = Auditable; diff --git a/templates/Audit.js b/templates/Audit.js index cdf9609..735e643 100644 --- a/templates/Audit.js +++ b/templates/Audit.js @@ -1,13 +1,13 @@ -'use strict' +"use strict"; -const Model = use('Model') +const Model = use("Model"); class Audit extends Model { /** * @returns {null} */ static get updatedAtColumn () { - return null + return null; } /** @@ -17,10 +17,10 @@ class Audit extends Model { */ static get events () { return Object.freeze({ - CREATE: 'create', - UPDATE: 'update', - DELETE: 'delete', - }) + CREATE: "create", + UPDATE: "update", + DELETE: "delete", + }); } /** @@ -29,7 +29,7 @@ class Audit extends Model { */ getOldData (value) { if (value) { - return JSON.parse(value) + return JSON.parse(value); } } @@ -39,7 +39,7 @@ class Audit extends Model { */ setOldData (value) { if (value !== null) { - return JSON.stringify(value) + return JSON.stringify(value); } } @@ -49,7 +49,7 @@ class Audit extends Model { */ getNewData (value) { if (value) { - return JSON.parse(value) + return JSON.parse(value); } } @@ -59,9 +59,9 @@ class Audit extends Model { */ setNewData (value) { if (value !== null) { - return JSON.stringify(value) + return JSON.stringify(value); } } } -module.exports = Audit +module.exports = Audit; diff --git a/templates/AuditSchema.js b/templates/AuditSchema.js index 1f9f6dd..5ee0d4d 100644 --- a/templates/AuditSchema.js +++ b/templates/AuditSchema.js @@ -1,26 +1,26 @@ -'use strict' +"use strict"; -const Schema = use('Schema') +const Schema = use("Schema"); class AuditSchema extends Schema { up () { - this.create('audits', (table) => { - table.increments() - table.integer('user_id').unsigned().references('id').inTable('users') - table.integer('auditable_id').notNullable().index() - table.string('auditable').notNullable() - table.string('event').notNullable() - table.string('ip', 45).notNullable() - table.text('url').notNullable() - table.text('old_data', 'longtext') - table.text('new_data', 'longtext') - table.dateTime('created_at') - }) + this.create("audits", (table) => { + table.increments(); + table.integer("user_id").unsigned().references("id").inTable("users"); + table.integer("auditable_id").notNullable().index(); + table.string("auditable").notNullable(); + table.string("event").notNullable(); + table.string("ip", 45).notNullable(); + table.text("url").notNullable(); + table.text("old_data", "longtext"); + table.text("new_data", "longtext"); + table.dateTime("created_at"); + }); } down () { - this.drop('audits') + this.drop("audits"); } } -module.exports = AuditSchema +module.exports = AuditSchema;