diff --git a/README.md b/README.md
index 70341b9a19..54cc834d69 100644
--- a/README.md
+++ b/README.md
@@ -15,7 +15,6 @@ Turns any MySQL, PostgreSQL, SQL Server, SQLite & MariaDB into a smart spreadshe
-[![Build Status](https://travis-ci.org/dwyl/esta.svg?branch=master)](https://travis-ci.com/github/NocoDB/NocoDB)
[![Node version](https://img.shields.io/badge/node-%3E%3D%2016.14.0-brightgreen)](http://nodejs.org/download/)
[![Conventional Commits](https://img.shields.io/badge/Conventional%20Commits-1.0.0-green.svg)](https://conventionalcommits.org)
diff --git a/packages/nc-cli/package-lock.json b/packages/nc-cli/package-lock.json
index a8336438a0..8aea25408c 100644
--- a/packages/nc-cli/package-lock.json
+++ b/packages/nc-cli/package-lock.json
@@ -135,19 +135,19 @@
"integrity": "sha512-dG76W7ElfLi+fbTjnZVGj+M9e0BIEJmRxU6fHaUQ12bZBe8EJKYb2GV50YWNaP2uJiVQ5+7nXEVj1VN1UQtaEw=="
},
"node_modules/@azure/ms-rest-js": {
- "version": "2.6.0",
- "resolved": "https://registry.npmjs.org/@azure/ms-rest-js/-/ms-rest-js-2.6.0.tgz",
- "integrity": "sha512-4C5FCtvEzWudblB+h92/TYYPiq7tuElX8icVYToxOdggnYqeec4Se14mjse5miInKtZahiFHdl8lZA/jziEc5g==",
+ "version": "2.6.6",
+ "resolved": "https://registry.npmjs.org/@azure/ms-rest-js/-/ms-rest-js-2.6.6.tgz",
+ "integrity": "sha512-WYIda8VvrkZE68xHgOxUXvjThxNf1nnGPPe0rAljqK5HJHIZ12Pi3YhEDOn3Ge7UnwaaM3eFO0VtAy4nGVI27Q==",
"dependencies": {
"@azure/core-auth": "^1.1.4",
"abort-controller": "^3.0.0",
"form-data": "^2.5.0",
- "node-fetch": "^2.6.0",
+ "node-fetch": "^2.6.7",
"tough-cookie": "^3.0.1",
"tslib": "^1.10.0",
"tunnel": "0.0.6",
"uuid": "^8.3.2",
- "xml2js": "^0.4.19"
+ "xml2js": "^0.5.0"
}
},
"node_modules/@azure/ms-rest-js/node_modules/tslib": {
@@ -9692,14 +9692,22 @@
"dev": true
},
"node_modules/node-fetch": {
- "version": "2.6.6",
- "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.6.tgz",
- "integrity": "sha512-Z8/6vRlTUChSdIgMa51jxQ4lrw/Jy5SOW10ObaA47/RElsAN2c5Pn8bTgFGWn/ibwzXTE8qwr1Yzx28vsecXEA==",
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.9.tgz",
+ "integrity": "sha512-DJm/CJkZkRjKKj4Zi4BsKVZh3ValV5IR5s7LVZnW+6YMh0W1BfNA8XSs6DLMGYlId5F3KnA70uu2qepcR08Qqg==",
"dependencies": {
"whatwg-url": "^5.0.0"
},
"engines": {
"node": "4.x || >=6.0.0"
+ },
+ "peerDependencies": {
+ "encoding": "^0.1.0"
+ },
+ "peerDependenciesMeta": {
+ "encoding": {
+ "optional": true
+ }
}
},
"node_modules/node-releases": {
@@ -15416,9 +15424,9 @@
}
},
"node_modules/xml2js": {
- "version": "0.4.23",
- "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.23.tgz",
- "integrity": "sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==",
+ "version": "0.5.0",
+ "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.5.0.tgz",
+ "integrity": "sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA==",
"dependencies": {
"sax": ">=0.6.0",
"xmlbuilder": "~11.0.0"
@@ -15576,19 +15584,19 @@
"integrity": "sha512-dG76W7ElfLi+fbTjnZVGj+M9e0BIEJmRxU6fHaUQ12bZBe8EJKYb2GV50YWNaP2uJiVQ5+7nXEVj1VN1UQtaEw=="
},
"@azure/ms-rest-js": {
- "version": "2.6.0",
- "resolved": "https://registry.npmjs.org/@azure/ms-rest-js/-/ms-rest-js-2.6.0.tgz",
- "integrity": "sha512-4C5FCtvEzWudblB+h92/TYYPiq7tuElX8icVYToxOdggnYqeec4Se14mjse5miInKtZahiFHdl8lZA/jziEc5g==",
+ "version": "2.6.6",
+ "resolved": "https://registry.npmjs.org/@azure/ms-rest-js/-/ms-rest-js-2.6.6.tgz",
+ "integrity": "sha512-WYIda8VvrkZE68xHgOxUXvjThxNf1nnGPPe0rAljqK5HJHIZ12Pi3YhEDOn3Ge7UnwaaM3eFO0VtAy4nGVI27Q==",
"requires": {
"@azure/core-auth": "^1.1.4",
"abort-controller": "^3.0.0",
"form-data": "^2.5.0",
- "node-fetch": "^2.6.0",
+ "node-fetch": "^2.6.7",
"tough-cookie": "^3.0.1",
"tslib": "^1.10.0",
"tunnel": "0.0.6",
"uuid": "^8.3.2",
- "xml2js": "^0.4.19"
+ "xml2js": "^0.5.0"
},
"dependencies": {
"tslib": {
@@ -22944,9 +22952,9 @@
"dev": true
},
"node-fetch": {
- "version": "2.6.6",
- "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.6.tgz",
- "integrity": "sha512-Z8/6vRlTUChSdIgMa51jxQ4lrw/Jy5SOW10ObaA47/RElsAN2c5Pn8bTgFGWn/ibwzXTE8qwr1Yzx28vsecXEA==",
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.9.tgz",
+ "integrity": "sha512-DJm/CJkZkRjKKj4Zi4BsKVZh3ValV5IR5s7LVZnW+6YMh0W1BfNA8XSs6DLMGYlId5F3KnA70uu2qepcR08Qqg==",
"requires": {
"whatwg-url": "^5.0.0"
}
@@ -27284,9 +27292,9 @@
}
},
"xml2js": {
- "version": "0.4.23",
- "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.23.tgz",
- "integrity": "sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==",
+ "version": "0.5.0",
+ "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.5.0.tgz",
+ "integrity": "sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA==",
"requires": {
"sax": ">=0.6.0",
"xmlbuilder": "~11.0.0"
diff --git a/packages/nc-gui/components/dashboard/settings/AuditTab.vue b/packages/nc-gui/components/dashboard/settings/AuditTab.vue
index d90fbc5931..3bbb386349 100644
--- a/packages/nc-gui/components/dashboard/settings/AuditTab.vue
+++ b/packages/nc-gui/components/dashboard/settings/AuditTab.vue
@@ -67,6 +67,7 @@ const columns = [
title: tableHeaderRenderer(t('labels.description')),
dataIndex: 'description',
key: 'description',
+ customRender: (value: { text: string }) => h('pre', {}, value.text),
},
{
// User
@@ -83,6 +84,7 @@ const columns = [
sort: 'desc',
customRender: (value: { text: string }) =>
h(ATooltip, { placement: 'bottom', title: h('span', {}, value.text) }, () => timeAgo(value.text)),
+ width: '10%',
},
]
@@ -110,7 +112,7 @@ const columns = [
+
+
diff --git a/packages/nc-gui/composables/useExpandedFormStore.ts b/packages/nc-gui/composables/useExpandedFormStore.ts
index 98e5769445..43a60991cc 100644
--- a/packages/nc-gui/composables/useExpandedFormStore.ts
+++ b/packages/nc-gui/composables/useExpandedFormStore.ts
@@ -7,7 +7,6 @@ import {
computed,
extractPkFromRow,
extractSdkResponseErrorMsg,
- getHTMLEncodedText,
message,
populateInsertObject,
ref,
@@ -127,7 +126,7 @@ const [useProvideExpandedFormStore, useExpandedFormStore] = useInjectionState((m
await api.utils.commentRow({
fk_model_id: meta.value?.id as string,
row_id: rowId,
- description: comment.value,
+ description: `The following comment has been created: ${comment.value}`,
})
comment.value = ''
@@ -253,22 +252,8 @@ const [useProvideExpandedFormStore, useExpandedFormStore] = useInjectionState((m
})
}
- for (const key of Object.keys(updateOrInsertObj)) {
- // audit
- $api.utils
- .auditRowUpdate(id, {
- fk_model_id: meta.value.id,
- column_name: key,
- row_id: id,
- value: getHTMLEncodedText(updateOrInsertObj[key]),
- prev_value: getHTMLEncodedText(row.value.oldRow[key]),
- })
- .then(async () => {
- /** load latest comments/audit if right drawer is open */
- if (commentsDrawer.value) {
- await loadCommentsAndLogs()
- }
- })
+ if (commentsDrawer.value) {
+ await loadCommentsAndLogs()
}
} else {
// No columns to update
diff --git a/packages/nc-gui/composables/useKanbanViewStore.ts b/packages/nc-gui/composables/useKanbanViewStore.ts
index 048663706f..e6241545a7 100644
--- a/packages/nc-gui/composables/useKanbanViewStore.ts
+++ b/packages/nc-gui/composables/useKanbanViewStore.ts
@@ -8,7 +8,6 @@ import {
enumColor,
extractPkFromRow,
extractSdkResponseErrorMsg,
- getHTMLEncodedText,
inject,
message,
parseProp,
@@ -401,14 +400,6 @@ const [useProvideKanbanViewStore, useKanbanViewStore] = useInjectionState(
// query: { ignoreWebhook: !saved }
// }
)
- // audit
- $api.utils.auditRowUpdate(id, {
- fk_model_id: meta.value?.id as string,
- column_name: property,
- row_id: id,
- value: getHTMLEncodedText(toUpdate.row[property]),
- prev_value: getHTMLEncodedText(toUpdate.oldRow[property]),
- })
if (!undo) {
const oldRowIndex = moveHistory.value.find((ele) => ele.op === 'removed' && ele.pk === id)
diff --git a/packages/nc-gui/composables/useViewData.ts b/packages/nc-gui/composables/useViewData.ts
index cddb3e50dd..e41c84743a 100644
--- a/packages/nc-gui/composables/useViewData.ts
+++ b/packages/nc-gui/composables/useViewData.ts
@@ -8,7 +8,6 @@ import {
computed,
extractPkFromRow,
extractSdkResponseErrorMsg,
- getHTMLEncodedText,
message,
populateInsertObject,
ref,
@@ -350,14 +349,6 @@ export function useViewData(
// query: { ignoreWebhook: !saved }
// }
)
- // audit
- $api.utils.auditRowUpdate(encodeURIComponent(id), {
- fk_model_id: metaValue?.id as string,
- column_name: property,
- row_id: id,
- value: getHTMLEncodedText(toUpdate.row[property]),
- prev_value: getHTMLEncodedText(toUpdate.oldRow[property]),
- })
if (!undo) {
addUndo({
diff --git a/packages/nc-gui/package-lock.json b/packages/nc-gui/package-lock.json
index 4670e0d396..5e1f791771 100644
--- a/packages/nc-gui/package-lock.json
+++ b/packages/nc-gui/package-lock.json
@@ -110,7 +110,7 @@
}
},
"../nocodb-sdk": {
- "version": "0.106.0-beta.1",
+ "version": "0.106.0",
"license": "AGPL-3.0-or-later",
"dependencies": {
"axios": "^0.21.1",
diff --git a/packages/nc-lib-gui/package.json b/packages/nc-lib-gui/package.json
index 8271dd57aa..77f00b9a2b 100644
--- a/packages/nc-lib-gui/package.json
+++ b/packages/nc-lib-gui/package.json
@@ -1,6 +1,6 @@
{
"name": "nc-lib-gui",
- "version": "0.106.0-beta.1",
+ "version": "0.106.0",
"description": "NocoDB GUI",
"author": {
"name": "NocoDB",
diff --git a/packages/nocodb-sdk/package-lock.json b/packages/nocodb-sdk/package-lock.json
index 49ccd0bb54..fd8dd25b31 100644
--- a/packages/nocodb-sdk/package-lock.json
+++ b/packages/nocodb-sdk/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "nocodb-sdk",
- "version": "0.106.0-beta.1",
+ "version": "0.106.0",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "nocodb-sdk",
- "version": "0.106.0-beta.1",
+ "version": "0.106.0",
"license": "AGPL-3.0-or-later",
"dependencies": {
"axios": "^0.21.1",
diff --git a/packages/nocodb-sdk/package.json b/packages/nocodb-sdk/package.json
index 3bffeb19d7..bbbc59a37d 100644
--- a/packages/nocodb-sdk/package.json
+++ b/packages/nocodb-sdk/package.json
@@ -1,6 +1,6 @@
{
"name": "nocodb-sdk",
- "version": "0.106.0-beta.1",
+ "version": "0.106.0",
"description": "NocoDB SDK",
"main": "build/main/index.js",
"typings": "build/main/index.d.ts",
diff --git a/packages/nocodb-sdk/src/lib/Api.ts b/packages/nocodb-sdk/src/lib/Api.ts
index b3b12a773e..2407419a29 100644
--- a/packages/nocodb-sdk/src/lib/Api.ts
+++ b/packages/nocodb-sdk/src/lib/Api.ts
@@ -154,13 +154,11 @@ export interface AuditType {
| 'LINK_RECORD'
| 'UNLINK_RECORD'
| 'DELETE'
- | 'CREATED'
- | 'DELETED'
- | 'RENAMED'
+ | 'CREATE'
+ | 'RENAME'
| 'IMPORT_FROM_ZIP'
| 'EXPORT_TO_FS'
| 'EXPORT_TO_ZIP'
- | 'UPDATED'
| 'SIGNIN'
| 'SIGNUP'
| 'PASSWORD_RESET'
diff --git a/packages/nocodb-sdk/src/lib/globals.ts b/packages/nocodb-sdk/src/lib/globals.ts
index fd64f2d2a8..4a53cb2c00 100644
--- a/packages/nocodb-sdk/src/lib/globals.ts
+++ b/packages/nocodb-sdk/src/lib/globals.ts
@@ -47,13 +47,11 @@ export enum AuditOperationSubTypes {
LINK_RECORD = 'LINK_RECORD',
UNLINK_RECORD = 'UNLINK_RECORD',
DELETE = 'DELETE',
- CREATED = 'CREATED',
- DELETED = 'DELETED',
- RENAMED = 'RENAMED',
+ CREATE = 'CREATE',
+ RENAME = 'RENAME',
IMPORT_FROM_ZIP = 'IMPORT_FROM_ZIP',
EXPORT_TO_FS = 'EXPORT_TO_FS',
EXPORT_TO_ZIP = 'EXPORT_TO_ZIP',
- UPDATED = 'UPDATED',
SIGNIN = 'SIGNIN',
SIGNUP = 'SIGNUP',
PASSWORD_RESET = 'PASSWORD_RESET',
diff --git a/packages/nocodb/package-lock.json b/packages/nocodb/package-lock.json
index 4df22008da..03e968567c 100644
--- a/packages/nocodb/package-lock.json
+++ b/packages/nocodb/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "nocodb",
- "version": "0.106.0-beta.1",
+ "version": "0.106.0",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "nocodb",
- "version": "0.106.0-beta.1",
+ "version": "0.106.0",
"license": "AGPL-3.0-or-later",
"dependencies": {
"@google-cloud/storage": "^5.7.2",
@@ -67,7 +67,7 @@
"mysql2": "^2.2.5",
"nanoid": "^3.1.20",
"nc-help": "0.2.87",
- "nc-lib-gui": "0.106.0-beta.1",
+ "nc-lib-gui": "0.106.0",
"nc-plugin": "0.1.2",
"ncp": "^2.0.0",
"nocodb-sdk": "file:../nocodb-sdk",
@@ -156,7 +156,7 @@
}
},
"../nocodb-sdk": {
- "version": "0.106.0-beta.1",
+ "version": "0.106.0",
"license": "AGPL-3.0-or-later",
"dependencies": {
"axios": "^0.21.1",
@@ -11330,9 +11330,9 @@
}
},
"node_modules/nc-lib-gui": {
- "version": "0.106.0-beta.1",
- "resolved": "https://registry.npmjs.org/nc-lib-gui/-/nc-lib-gui-0.106.0-beta.1.tgz",
- "integrity": "sha512-dewDGvwPjDsOlsAusXaoWJ92eNy8BF4YS8nYd3SJiEJKIv27vllDGMe4TN1SdBkKHbg0kvMffSrldPHcFQtRvQ==",
+ "version": "0.106.0",
+ "resolved": "https://registry.npmjs.org/nc-lib-gui/-/nc-lib-gui-0.106.0.tgz",
+ "integrity": "sha512-BZDheNWKi+iKo5MfOKaxmYT6piNQ3K6SgrH3lH5PhTGzjN9dM+xs0Y+Wgo8r8rjNQj6pNEB17IuMZK3amCntxQ==",
"dependencies": {
"express": "^4.17.1"
}
@@ -17364,9 +17364,9 @@
"dev": true
},
"node_modules/vm2": {
- "version": "3.9.13",
- "resolved": "https://registry.npmjs.org/vm2/-/vm2-3.9.13.tgz",
- "integrity": "sha512-0rvxpB8P8Shm4wX2EKOiMp7H2zq+HUE/UwodY0pCZXs9IffIKZq6vUti5OgkVCTakKo9e/fgO4X1fkwfjWxE3Q==",
+ "version": "3.9.15",
+ "resolved": "https://registry.npmjs.org/vm2/-/vm2-3.9.15.tgz",
+ "integrity": "sha512-XqNqknHGw2avJo13gbIwLNZUumvrSHc9mLqoadFZTpo3KaNEJoe1I0lqTFhRXmXD7WkLyG01aaraXdXT0pa4ag==",
"dependencies": {
"acorn": "^8.7.0",
"acorn-walk": "^8.2.0"
@@ -28042,9 +28042,9 @@
}
},
"nc-lib-gui": {
- "version": "0.106.0-beta.1",
- "resolved": "https://registry.npmjs.org/nc-lib-gui/-/nc-lib-gui-0.106.0-beta.1.tgz",
- "integrity": "sha512-dewDGvwPjDsOlsAusXaoWJ92eNy8BF4YS8nYd3SJiEJKIv27vllDGMe4TN1SdBkKHbg0kvMffSrldPHcFQtRvQ==",
+ "version": "0.106.0",
+ "resolved": "https://registry.npmjs.org/nc-lib-gui/-/nc-lib-gui-0.106.0.tgz",
+ "integrity": "sha512-BZDheNWKi+iKo5MfOKaxmYT6piNQ3K6SgrH3lH5PhTGzjN9dM+xs0Y+Wgo8r8rjNQj6pNEB17IuMZK3amCntxQ==",
"requires": {
"express": "^4.17.1"
}
@@ -32786,9 +32786,9 @@
"dev": true
},
"vm2": {
- "version": "3.9.13",
- "resolved": "https://registry.npmjs.org/vm2/-/vm2-3.9.13.tgz",
- "integrity": "sha512-0rvxpB8P8Shm4wX2EKOiMp7H2zq+HUE/UwodY0pCZXs9IffIKZq6vUti5OgkVCTakKo9e/fgO4X1fkwfjWxE3Q==",
+ "version": "3.9.15",
+ "resolved": "https://registry.npmjs.org/vm2/-/vm2-3.9.15.tgz",
+ "integrity": "sha512-XqNqknHGw2avJo13gbIwLNZUumvrSHc9mLqoadFZTpo3KaNEJoe1I0lqTFhRXmXD7WkLyG01aaraXdXT0pa4ag==",
"requires": {
"acorn": "^8.7.0",
"acorn-walk": "^8.2.0"
diff --git a/packages/nocodb/package.json b/packages/nocodb/package.json
index 4411bf9395..b9e5dee05b 100644
--- a/packages/nocodb/package.json
+++ b/packages/nocodb/package.json
@@ -1,6 +1,6 @@
{
"name": "nocodb",
- "version": "0.106.0-beta.1",
+ "version": "0.106.0",
"description": "NocoDB Backend",
"main": "dist/bundle.js",
"author": {
@@ -109,7 +109,7 @@
"mysql2": "^2.2.5",
"nanoid": "^3.1.20",
"nc-help": "0.2.87",
- "nc-lib-gui": "0.106.0-beta.1",
+ "nc-lib-gui": "0.106.0",
"nc-plugin": "0.1.2",
"ncp": "^2.0.0",
"nocodb-sdk": "file:../nocodb-sdk",
diff --git a/packages/nocodb/src/lib/controllers/user/user.ctl.ts b/packages/nocodb/src/lib/controllers/user/user.ctl.ts
index b411db0e39..c68ada72f7 100644
--- a/packages/nocodb/src/lib/controllers/user/user.ctl.ts
+++ b/packages/nocodb/src/lib/controllers/user/user.ctl.ts
@@ -1,4 +1,5 @@
import { promisify } from 'util';
+import { AuditOperationSubTypes, AuditOperationTypes } from 'nocodb-sdk';
import * as ejs from 'ejs';
import passport from 'passport';
import catchError, { NcError } from '../../meta/helpers/catchError';
@@ -65,8 +66,8 @@ async function successfulSignIn({
setTokenCookie(res, refreshToken);
await Audit.insert({
- op_type: 'AUTHENTICATION',
- op_sub_type: 'SIGNIN',
+ op_type: AuditOperationTypes.AUTHENTICATION,
+ op_sub_type: AuditOperationSubTypes.SIGNIN,
user: user.email,
ip: req.clientIp,
description: auditDescription,
@@ -92,7 +93,7 @@ async function signin(req, res, next) {
info,
req,
res,
- auditDescription: 'signed in',
+ auditDescription: 'User has signed in successfully',
})
)(req, res, next);
}
@@ -111,7 +112,7 @@ async function googleSignin(req, res, next) {
info,
req,
res,
- auditDescription: 'signed in using Google Auth',
+ auditDescription: 'User has signed in successfully using Google Auth ',
})
)(req, res, next);
}
diff --git a/packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/BaseModelSqlv2.ts b/packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/BaseModelSqlv2.ts
index 14dd6bbe0d..2890fd3508 100644
--- a/packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/BaseModelSqlv2.ts
+++ b/packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/BaseModelSqlv2.ts
@@ -1864,7 +1864,7 @@ class BaseModelSqlv2 {
await this.execAndParse(query);
const newData = await this.readByPk(id);
- await this.afterUpdate(prevData, newData, trx, cookie);
+ await this.afterUpdate(prevData, newData, trx, cookie, updateObj);
return newData;
} catch (e) {
console.log(e);
@@ -2296,7 +2296,7 @@ class BaseModelSqlv2 {
op_type: AuditOperationTypes.DATA,
op_sub_type: AuditOperationSubTypes.INSERT,
description: DOMPurify.sanitize(
- `${id} inserted into ${this.model.title}`
+ `Record with ID ${id} has been inserted into Table ${this.model.title}`
),
// details: JSON.stringify(data),
ip: req?.clientIp,
@@ -2322,7 +2322,9 @@ class BaseModelSqlv2 {
op_type: AuditOperationTypes.DATA,
op_sub_type: AuditOperationSubTypes.BULK_UPDATE,
description: DOMPurify.sanitize(
- `${noOfUpdatedRecords} records bulk updated in ${this.model.title}`
+ `${noOfUpdatedRecords} ${
+ noOfUpdatedRecords > 1 ? 'records have' : 'record has'
+ } been bulk updated in ${this.model.title}`
),
// details: JSON.stringify(data),
ip: req?.clientIp,
@@ -2347,7 +2349,9 @@ class BaseModelSqlv2 {
op_type: AuditOperationTypes.DATA,
op_sub_type: AuditOperationSubTypes.BULK_DELETE,
description: DOMPurify.sanitize(
- `${noOfDeletedRecords} records bulk deleted in ${this.model.title}`
+ `${noOfDeletedRecords} ${
+ noOfDeletedRecords > 1 ? 'records have' : 'record has'
+ } been bulk deleted in ${this.model.title}`
),
// details: JSON.stringify(data),
ip: req?.clientIp,
@@ -2363,7 +2367,9 @@ class BaseModelSqlv2 {
op_type: AuditOperationTypes.DATA,
op_sub_type: AuditOperationSubTypes.BULK_INSERT,
description: DOMPurify.sanitize(
- `${data.length} records bulk inserted into ${this.model.title}`
+ `${data.length} ${
+ data.length > 1 ? 'records have' : 'record has'
+ } been bulk inserted in ${this.model.title}`
),
// details: JSON.stringify(data),
ip: req?.clientIp,
@@ -2387,16 +2393,32 @@ class BaseModelSqlv2 {
prevData: any,
newData: any,
_trx: any,
- req
+ req,
+ updateObj?: Record
): Promise {
const id = this._extractPksValues(newData);
-
+ let desc = `Record with ID ${id} has been updated in Table ${this.model.title}.`;
+ if (updateObj) {
+ updateObj = await this.model.mapColumnToAlias(updateObj);
+ for (const k of Object.keys(updateObj)) {
+ const prevValue =
+ typeof prevData[k] === 'object'
+ ? JSON.stringify(prevData[k])
+ : prevData[k];
+ const newValue =
+ typeof newData[k] === 'object'
+ ? JSON.stringify(newData[k])
+ : newData[k];
+ desc += `\n`;
+ desc += `Column "${k}" got changed from "${prevValue}" to "${newValue}"`;
+ }
+ }
await Audit.insert({
fk_model_id: this.model.id,
row_id: id,
op_type: AuditOperationTypes.DATA,
op_sub_type: AuditOperationSubTypes.UPDATE,
- description: DOMPurify.sanitize(`${id} updated in ${this.model.title}`),
+ description: DOMPurify.sanitize(desc),
// details: JSON.stringify(data),
ip: req?.clientIp,
user: req?.user?.email,
@@ -2424,7 +2446,9 @@ class BaseModelSqlv2 {
row_id: id,
op_type: AuditOperationTypes.DATA,
op_sub_type: AuditOperationSubTypes.DELETE,
- description: DOMPurify.sanitize(`${id} deleted from ${this.model.title}`),
+ description: DOMPurify.sanitize(
+ `Record with ID ${id} has been deleted in Table ${this.model.title}`
+ ),
// details: JSON.stringify(data),
ip: req?.clientIp,
user: req?.user?.email,
@@ -2695,7 +2719,7 @@ class BaseModelSqlv2 {
op_sub_type: AuditOperationSubTypes.LINK_RECORD,
row_id: rowId,
description: DOMPurify.sanitize(
- `Record [id:${childId}] record linked with record [id:${rowId}] record in ${this.model.title}`
+ `Record [id:${childId}] has been linked with record [id:${rowId}] in ${this.model.title}`
),
// details: JSON.stringify(data),
ip: req?.clientIp,
@@ -2797,7 +2821,7 @@ class BaseModelSqlv2 {
op_sub_type: AuditOperationSubTypes.UNLINK_RECORD,
row_id: rowId,
description: DOMPurify.sanitize(
- `Record [id:${childId}] record unlinked with record [id:${rowId}] record in ${this.model.title}`
+ `Record [id:${childId}] has been unlinked with record [id:${rowId}] in ${this.model.title}`
),
// details: JSON.stringify(data),
ip: req?.clientIp,
diff --git a/packages/nocodb/src/lib/models/Audit.ts b/packages/nocodb/src/lib/models/Audit.ts
index f8e2e84bb9..0f01e1b1ef 100644
--- a/packages/nocodb/src/lib/models/Audit.ts
+++ b/packages/nocodb/src/lib/models/Audit.ts
@@ -30,13 +30,11 @@ const opSubTypes = [
'LINK_RECORD',
'UNLINK_RECORD',
'DELETE',
- 'CREATED',
- 'DELETED',
- 'RENAMED',
+ 'CREATE',
+ 'RENAME',
'IMPORT_FROM_ZIP',
'EXPORT_TO_FS',
'EXPORT_TO_ZIP',
- 'UPDATED',
'SIGNIN',
'SIGNUP',
'PASSWORD_RESET',
diff --git a/packages/nocodb/src/lib/models/Model.ts b/packages/nocodb/src/lib/models/Model.ts
index aa1b4486ae..23523d60ad 100644
--- a/packages/nocodb/src/lib/models/Model.ts
+++ b/packages/nocodb/src/lib/models/Model.ts
@@ -463,6 +463,24 @@ export default class Model implements TableType {
return insertObj;
}
+ async mapColumnToAlias(data) {
+ const res = {};
+ for (const col of await this.getColumns()) {
+ if (isVirtualCol(col)) continue;
+ let val =
+ data?.[col.title] !== undefined
+ ? data?.[col.title]
+ : data?.[col.column_name];
+ if (val !== undefined) {
+ if (col.uidt === UITypes.Attachment && typeof val !== 'string') {
+ val = JSON.stringify(val);
+ }
+ res[sanitize(col.title)] = val;
+ }
+ }
+ return res;
+ }
+
static async updateAliasAndTableName(
tableId,
title: string,
diff --git a/packages/nocodb/src/lib/services/audit.svc.ts b/packages/nocodb/src/lib/services/audit.svc.ts
index d88fdf5e26..c941800827 100644
--- a/packages/nocodb/src/lib/services/audit.svc.ts
+++ b/packages/nocodb/src/lib/services/audit.svc.ts
@@ -36,7 +36,7 @@ export async function auditRowUpdate(param: {
op_type: AuditOperationTypes.DATA,
op_sub_type: AuditOperationSubTypes.UPDATE,
description: DOMPurify.sanitize(
- `Table ${model.table_name} : field ${param.body.column_name} got changed from ${param.body.prev_value} to ${param.body.value}`
+ `The column ${param.body.column_name} in Table ${model.table_name} has been changed from ${param.body.prev_value} to ${param.body.value}`
),
details: DOMPurify.sanitize(`${param.body.column_name}
: ${param.body.prev_value}
diff --git a/packages/nocodb/src/lib/services/column.svc.ts b/packages/nocodb/src/lib/services/column.svc.ts
index 4ff0a6ea10..4fa6a6c5ef 100644
--- a/packages/nocodb/src/lib/services/column.svc.ts
+++ b/packages/nocodb/src/lib/services/column.svc.ts
@@ -822,9 +822,9 @@ export async function columnUpdate(param: {
await Audit.insert({
project_id: base.project_id,
op_type: AuditOperationTypes.TABLE_COLUMN,
- op_sub_type: AuditOperationSubTypes.UPDATED,
+ op_sub_type: AuditOperationSubTypes.UPDATE,
user: param.req?.user?.email,
- description: `updated column ${column.column_name} with alias ${column.title} from table ${table.table_name}`,
+ description: `The column ${column.column_name} with alias ${column.title} from table ${table.table_name} has been updated`,
ip: param.req?.clientIp,
}).then(() => {});
@@ -1127,9 +1127,9 @@ export async function columnAdd(param: {
await Audit.insert({
project_id: base.project_id,
op_type: AuditOperationTypes.TABLE_COLUMN,
- op_sub_type: AuditOperationSubTypes.CREATED,
+ op_sub_type: AuditOperationSubTypes.CREATE,
user: param?.req.user?.email,
- description: `created column ${colBody.column_name} with alias ${colBody.title} from table ${table.table_name}`,
+ description: `The column ${colBody.column_name} with alias ${colBody.title} from table ${table.table_name} has been created`,
ip: param?.req.clientIp,
}).then(() => {});
@@ -1339,9 +1339,9 @@ export async function columnDelete(param: { req?: any; columnId: string }) {
await Audit.insert({
project_id: base.project_id,
op_type: AuditOperationTypes.TABLE_COLUMN,
- op_sub_type: AuditOperationSubTypes.DELETED,
+ op_sub_type: AuditOperationSubTypes.DELETE,
user: param?.req?.user?.email,
- description: `deleted column ${column.column_name} with alias ${column.title} from table ${table.table_name}`,
+ description: `The column ${column.column_name} with alias ${column.title} from table ${table.table_name} has been deleted`,
ip: param?.req.clientIp,
}).then(() => {});
diff --git a/packages/nocodb/src/lib/services/orgUser.svc.ts b/packages/nocodb/src/lib/services/orgUser.svc.ts
index a3f79d0d2a..38c19bf9a1 100644
--- a/packages/nocodb/src/lib/services/orgUser.svc.ts
+++ b/packages/nocodb/src/lib/services/orgUser.svc.ts
@@ -147,7 +147,7 @@ export async function userAdd(param: {
op_type: AuditOperationTypes.ORG_USER,
op_sub_type: AuditOperationSubTypes.INVITE,
user: param.req.user.email,
- description: `invited ${email} to ${param.projectId} project `,
+ description: `${email} has been invited to ${param.projectId} project`,
ip: param.req.clientIp,
});
// in case of single user check for smtp failure
@@ -218,7 +218,7 @@ export async function userInviteResend(param: {
op_type: AuditOperationTypes.ORG_USER,
op_sub_type: AuditOperationSubTypes.RESEND_INVITE,
user: user.email,
- description: `resent a invite to ${user.email} `,
+ description: `${user.email} has been re-invited`,
ip: param.req.clientIp,
});
diff --git a/packages/nocodb/src/lib/services/projectUser.svc.ts b/packages/nocodb/src/lib/services/projectUser.svc.ts
index bc60f7a844..bd3d7a2b4c 100644
--- a/packages/nocodb/src/lib/services/projectUser.svc.ts
+++ b/packages/nocodb/src/lib/services/projectUser.svc.ts
@@ -1,9 +1,13 @@
-import { OrgUserRoles } from 'nocodb-sdk';
+import {
+ AuditOperationSubTypes,
+ AuditOperationTypes,
+ OrgUserRoles,
+ PluginCategory,
+} from 'nocodb-sdk';
import { T } from 'nc-help';
import validator from 'validator';
import { v4 as uuidv4 } from 'uuid';
import * as ejs from 'ejs';
-import { PluginCategory } from 'nocodb-sdk';
import { validatePayload } from '../meta/api/helpers';
import { PagedResponseImpl } from '../meta/helpers/PagedResponse';
import ProjectUser from '../models/ProjectUser';
@@ -91,10 +95,10 @@ export async function userInvite(param: {
await Audit.insert({
project_id: param.projectId,
- op_type: 'AUTHENTICATION',
- op_sub_type: 'INVITE',
+ op_type: AuditOperationTypes.AUTHENTICATION,
+ op_sub_type: AuditOperationSubTypes.INVITE,
user: param.req.user.email,
- description: `invited ${email} to ${param.projectId} project `,
+ description: `${email} has been invited to ${param.projectId} project`,
ip: param.req.clientIp,
});
} else {
@@ -120,8 +124,8 @@ export async function userInvite(param: {
await Audit.insert({
project_id: param.projectId,
- op_type: 'AUTHENTICATION',
- op_sub_type: 'INVITE',
+ op_type: AuditOperationTypes.AUTHENTICATION,
+ op_sub_type: AuditOperationSubTypes.INVITE,
user: param.req.user.email,
description: `invited ${email} to ${param.projectId} project `,
ip: param.req.clientIp,
@@ -202,10 +206,10 @@ export async function projectUserUpdate(param: {
);
await Audit.insert({
- op_type: 'AUTHENTICATION',
- op_sub_type: 'ROLES_MANAGEMENT',
+ op_type: AuditOperationTypes.AUTHENTICATION,
+ op_sub_type: AuditOperationSubTypes.ROLES_MANAGEMENT,
user: param.req.user.email,
- description: `updated roles for ${user.email} with ${param.projectUser.roles} `,
+ description: `Roles for ${user.email} with has been updated to ${param.projectUser.roles}`,
ip: param.req.clientIp,
});
@@ -274,10 +278,10 @@ export async function projectUserInviteResend(param: {
await sendInviteEmail(user.email, invite_token, param.req);
await Audit.insert({
- op_type: 'AUTHENTICATION',
- op_sub_type: 'RESEND_INVITE',
+ op_type: AuditOperationTypes.AUTHENTICATION,
+ op_sub_type: AuditOperationSubTypes.RESEND_INVITE,
user: user.email,
- description: `resent a invite to ${user.email} `,
+ description: `${user.email} has been re-invited`,
ip: param.req.clientIp,
project_id: param.projectId,
});
diff --git a/packages/nocodb/src/lib/services/table.svc.ts b/packages/nocodb/src/lib/services/table.svc.ts
index 94e782a593..fa36f647a3 100644
--- a/packages/nocodb/src/lib/services/table.svc.ts
+++ b/packages/nocodb/src/lib/services/table.svc.ts
@@ -185,7 +185,7 @@ export async function tableDelete(param: {
project_id: project.id,
base_id: base.id,
op_type: AuditOperationTypes.TABLE,
- op_sub_type: AuditOperationSubTypes.DELETED,
+ op_sub_type: AuditOperationSubTypes.DELETE,
user: param.user?.email,
description: `Deleted ${table.type} ${table.table_name} with alias ${table.title} `,
ip: param.req?.clientIp,
@@ -433,9 +433,9 @@ export async function tableCreate(param: {
project_id: project.id,
base_id: base.id,
op_type: AuditOperationTypes.TABLE,
- op_sub_type: AuditOperationSubTypes.CREATED,
+ op_sub_type: AuditOperationSubTypes.CREATE,
user: param.user?.email,
- description: `created table ${tableCreatePayLoad.table_name} with alias ${tableCreatePayLoad.title} `,
+ description: `Table ${tableCreatePayLoad.table_name} with alias ${tableCreatePayLoad.title} has been created`,
ip: param.req?.clientIp,
}).then(() => {});
diff --git a/packages/nocodb/src/lib/services/user/index.ts b/packages/nocodb/src/lib/services/user/index.ts
index a082ff9070..1afa86648e 100644
--- a/packages/nocodb/src/lib/services/user/index.ts
+++ b/packages/nocodb/src/lib/services/user/index.ts
@@ -1,6 +1,10 @@
import { promisify } from 'util';
-import { validatePassword } from 'nocodb-sdk';
-import { OrgUserRoles } from 'nocodb-sdk';
+import {
+ AuditOperationSubTypes,
+ AuditOperationTypes,
+ OrgUserRoles,
+ validatePassword,
+} from 'nocodb-sdk';
import { T } from 'nc-help';
import * as ejs from 'ejs';
import bcrypt from 'bcryptjs';
@@ -120,10 +124,10 @@ export async function passwordChange(param: {
});
await Audit.insert({
- op_type: 'AUTHENTICATION',
- op_sub_type: 'PASSWORD_CHANGE',
+ op_type: AuditOperationTypes.AUTHENTICATION,
+ op_sub_type: AuditOperationSubTypes.PASSWORD_CHANGE,
user: user.email,
- description: `changed password `,
+ description: `Password has been changed`,
ip: param.req?.clientIp,
});
@@ -178,10 +182,10 @@ export async function passwordForgot(param: {
}
await Audit.insert({
- op_type: 'AUTHENTICATION',
- op_sub_type: 'PASSWORD_FORGOT',
+ op_type: AuditOperationTypes.AUTHENTICATION,
+ op_sub_type: AuditOperationSubTypes.PASSWORD_FORGOT,
user: user.email,
- description: `requested for password reset `,
+ description: `Password Reset has been requested`,
ip: param.req?.clientIp,
});
} else {
@@ -254,10 +258,10 @@ export async function passwordReset(param: {
});
await Audit.insert({
- op_type: 'AUTHENTICATION',
- op_sub_type: 'PASSWORD_RESET',
+ op_type: AuditOperationTypes.AUTHENTICATION,
+ op_sub_type: AuditOperationSubTypes.PASSWORD_RESET,
user: user.email,
- description: `did reset password `,
+ description: `Password has been reset`,
ip: req.clientIp,
});
@@ -286,10 +290,10 @@ export async function emailVerification(param: {
});
await Audit.insert({
- op_type: 'AUTHENTICATION',
- op_sub_type: 'EMAIL_VERIFICATION',
+ op_type: AuditOperationTypes.AUTHENTICATION,
+ op_sub_type: AuditOperationSubTypes.EMAIL_VERIFICATION,
user: user.email,
- description: `verified email `,
+ description: `Email has been verified`,
ip: req.clientIp,
});
@@ -442,10 +446,10 @@ export async function signup(param: {
user = (param.req as any).user;
await Audit.insert({
- op_type: 'AUTHENTICATION',
- op_sub_type: 'SIGNUP',
+ op_type: AuditOperationTypes.AUTHENTICATION,
+ op_sub_type: AuditOperationSubTypes.SIGNUP,
user: user.email,
- description: `signed up `,
+ description: `User has signed up`,
ip: (param.req as any).clientIp,
});
diff --git a/packages/nocodb/src/schema/swagger.json b/packages/nocodb/src/schema/swagger.json
index caa9c9002c..1fcfc3e4eb 100644
--- a/packages/nocodb/src/schema/swagger.json
+++ b/packages/nocodb/src/schema/swagger.json
@@ -14020,13 +14020,11 @@
"LINK_RECORD",
"UNLINK_RECORD",
"DELETE",
- "CREATED",
- "DELETED",
- "RENAMED",
+ "CREATE",
+ "RENAME",
"IMPORT_FROM_ZIP",
"EXPORT_TO_FS",
"EXPORT_TO_ZIP",
- "UPDATED",
"SIGNIN",
"SIGNUP",
"PASSWORD_RESET",
diff --git a/packages/nocodb/tests/unit/model/tests/baseModelSql.test.ts b/packages/nocodb/tests/unit/model/tests/baseModelSql.test.ts
index 16054c7f3e..cf7c52fbd6 100644
--- a/packages/nocodb/tests/unit/model/tests/baseModelSql.test.ts
+++ b/packages/nocodb/tests/unit/model/tests/baseModelSql.test.ts
@@ -78,7 +78,7 @@ function baseModelSqlTests() {
row_id: '1',
op_type: 'DATA',
op_sub_type: 'INSERT',
- description: '1 inserted into Table1_Title',
+ description: 'Record with ID 1 has been inserted into Table Table1_Title',
});
});
@@ -123,7 +123,7 @@ function baseModelSqlTests() {
op_type: 'DATA',
op_sub_type: 'BULK_INSERT',
status: null,
- description: '10 records bulk inserted into Table1_Title',
+ description: '10 records have been bulk inserted in Table1_Title',
details: null,
});
});
@@ -156,7 +156,7 @@ function baseModelSqlTests() {
row_id: '1',
op_type: 'DATA',
op_sub_type: 'UPDATE',
- description: '1 updated in Table1_Title',
+ description: 'Record with ID 1 has been updated in Table Table1_Title.\nColumn "Title" got changed from "test-0" to "test"',
});
});
@@ -199,7 +199,7 @@ function baseModelSqlTests() {
op_type: 'DATA',
op_sub_type: 'BULK_UPDATE',
status: null,
- description: '10 records bulk updated in Table1_Title',
+ description: '10 records have been bulk updated in Table1_Title',
details: null,
});
});
@@ -250,7 +250,7 @@ function baseModelSqlTests() {
op_type: 'DATA',
op_sub_type: 'BULK_UPDATE',
status: null,
- description: '4 records bulk updated in Table1_Title',
+ description: '4 records have been bulk updated in Table1_Title',
details: null,
});
});
@@ -288,7 +288,7 @@ function baseModelSqlTests() {
row_id: '1',
op_type: 'DATA',
op_sub_type: 'DELETE',
- description: '1 deleted from Table1_Title',
+ description: 'Record with ID 1 has been deleted in Table Table1_Title',
});
});
@@ -330,7 +330,7 @@ function baseModelSqlTests() {
op_type: 'DATA',
op_sub_type: 'BULK_DELETE',
status: null,
- description: '4 records bulk deleted in Table1_Title',
+ description: '4 records have been bulk deleted in Table1_Title',
details: null,
});
});
@@ -378,7 +378,7 @@ function baseModelSqlTests() {
op_type: 'DATA',
op_sub_type: 'BULK_DELETE',
status: null,
- description: '4 records bulk deleted in Table1_Title',
+ description: '4 records have been bulk deleted in Table1_Title',
details: null,
});
});
@@ -438,7 +438,7 @@ function baseModelSqlTests() {
row_id: '1',
op_type: 'DATA',
op_sub_type: 'INSERT',
- description: '1 inserted into Table1_Title',
+ description: 'Record with ID 1 has been inserted into Table Table1_Title',
});
});
@@ -506,7 +506,7 @@ function baseModelSqlTests() {
op_type: 'DATA',
op_sub_type: 'LINK_RECORD',
description:
- 'Record [id:1] record linked with record [id:1] record in Table1_Title',
+ 'Record [id:1] has been linked with record [id:1] in Table1_Title',
});
});
@@ -581,7 +581,7 @@ function baseModelSqlTests() {
op_type: 'DATA',
op_sub_type: 'UNLINK_RECORD',
description:
- 'Record [id:1] record unlinked with record [id:1] record in Table1_Title',
+ 'Record [id:1] has been unlinked with record [id:1] in Table1_Title',
});
});
}
diff --git a/tests/playwright/tests/tableOperations.spec.ts b/tests/playwright/tests/tableOperations.spec.ts
index e31821f9c0..9a2d56ebea 100644
--- a/tests/playwright/tests/tableOperations.spec.ts
+++ b/tests/playwright/tests/tableOperations.spec.ts
@@ -25,13 +25,13 @@ test.describe('Table Operations', () => {
await settings.audit.verifyRow({
index: 0,
opType: 'TABLE',
- opSubtype: 'DELETED',
+ opSubtype: 'DELETE',
user: 'user@nocodb.com',
});
await settings.audit.verifyRow({
index: 1,
opType: 'TABLE',
- opSubtype: 'CREATED',
+ opSubtype: 'CREATE',
user: 'user@nocodb.com',
});
await settings.close();