mirror of
https://github.com/nocodb/nocodb.git
synced 2026-02-01 23:48:33 +00:00
1
.gitignore
vendored
1
.gitignore
vendored
@@ -78,3 +78,4 @@ mongod
|
||||
|
||||
.history
|
||||
/packages/nocodb/docker/main.js.LICENSE.txt
|
||||
/packages/nocodb/noco_log.db
|
||||
|
||||
@@ -718,13 +718,15 @@ export default class NcProjectBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
res.json({
|
||||
const result = {
|
||||
info,
|
||||
aggregatedInfo: {
|
||||
list: this.apiInfInfoList,
|
||||
aggregated: this.aggregatedApiInfo
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
res.json(result);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -32,6 +32,8 @@ import {RestApiBuilder} from "./rest/RestApiBuilder";
|
||||
import RestAuthCtrlCE from "./rest/RestAuthCtrl";
|
||||
import RestAuthCtrlEE from "./rest/RestAuthCtrlEE";
|
||||
import mkdirp from 'mkdirp';
|
||||
import MetaAPILogger from "./meta/MetaAPILogger";
|
||||
|
||||
const log = debug('nc:app');
|
||||
require('dotenv').config();
|
||||
|
||||
@@ -177,7 +179,7 @@ export default class Noco {
|
||||
/******************* Middlewares : start *******************/
|
||||
this.router.use((req: any, _res, next) => {
|
||||
req.nc = this.requestContext;
|
||||
req.ncSiteUrl = this.config?.envs?.[this.env]?.publicUrl || this.config?.publicUrl || (req.protocol + '://' + req.get('host'));
|
||||
req.ncSiteUrl = this.config?.envs?.[this.env]?.publicUrl || this.config?.publicUrl || (req.protocol + '://' + req.get('host'));
|
||||
req.ncFullUrl = req.protocol + '://' + req.get('host') + req.originalUrl;
|
||||
next();
|
||||
});
|
||||
@@ -205,6 +207,7 @@ export default class Noco {
|
||||
req.ncProjectId = req.ncProjectId || req.params.project_id;
|
||||
next();
|
||||
})
|
||||
this.router.use(MetaAPILogger.mw);
|
||||
|
||||
/******************* Middlewares : end *******************/
|
||||
|
||||
|
||||
115
packages/nocodb/src/lib/noco/meta/MetaAPILogger.ts
Normal file
115
packages/nocodb/src/lib/noco/meta/MetaAPILogger.ts
Normal file
@@ -0,0 +1,115 @@
|
||||
import {XKnex} from "../../dataMapper";
|
||||
import {Request} from 'express';
|
||||
|
||||
export default class MetaAPILogger {
|
||||
|
||||
static _instance: MetaAPILogger;
|
||||
knex: XKnex;
|
||||
|
||||
constructor() {
|
||||
this.knex = XKnex({
|
||||
client: 'sqlite3',
|
||||
connection: {
|
||||
filename: 'noco_log.db'
|
||||
},
|
||||
useNullAsDefault: true
|
||||
})
|
||||
}
|
||||
|
||||
async init() {
|
||||
await this.knex.migrate.latest({
|
||||
migrationSource: new XcLoggerMigrationSource(),
|
||||
tableName: 'xc_knex_migrations'
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
static async mw(req, res, next) {
|
||||
|
||||
if (process.env.NC_LOGGER) {
|
||||
const oldWrite = res.write,
|
||||
oldEnd = res.end;
|
||||
|
||||
const chunks = [];
|
||||
|
||||
res.write = function (chunk) {
|
||||
chunks.push(chunk);
|
||||
|
||||
// eslint-disable-next-line prefer-rest-params
|
||||
oldWrite.apply(res, arguments);
|
||||
};
|
||||
|
||||
res.end = function (chunk) {
|
||||
if (chunk)
|
||||
chunks.push(chunk);
|
||||
|
||||
const body = Buffer.concat(chunks).toString('utf8');
|
||||
|
||||
MetaAPILogger.log(req, body)
|
||||
// eslint-disable-next-line prefer-rest-params
|
||||
oldEnd.apply(res, arguments);
|
||||
};
|
||||
}
|
||||
next();
|
||||
}
|
||||
|
||||
private static async log(req: Request, res: any) {
|
||||
if (!process.env.NC_LOGGER) {
|
||||
return;
|
||||
}
|
||||
if (!this._instance) {
|
||||
this._instance = new MetaAPILogger();
|
||||
await this._instance.init()
|
||||
}
|
||||
await this._instance.knex('nc_log').insert({
|
||||
path: req.url,
|
||||
params: JSON.stringify(req.query),
|
||||
body: JSON.stringify(req.body),
|
||||
headers: JSON.stringify(req.headers),
|
||||
method: req.method,
|
||||
operation: req.body?.api,
|
||||
response: typeof res === 'string' ? res : JSON.stringify(res)
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
class XcLoggerMigrationSource {
|
||||
// Must return a Promise containing a list of migrations.
|
||||
// Migrations can be whatever you want, they will be passed as
|
||||
// arguments to getMigrationName and getMigration
|
||||
public getMigrations(): Promise<any> {
|
||||
// In this example we are just returning migration names
|
||||
return Promise.resolve(['logger'])
|
||||
}
|
||||
|
||||
public getMigrationName(migration): string {
|
||||
return migration;
|
||||
}
|
||||
|
||||
public getMigration(migration): any {
|
||||
switch (migration) {
|
||||
case 'logger':
|
||||
return {
|
||||
async up(knex: XKnex) {
|
||||
await knex.schema.createTable('nc_log', table => {
|
||||
table.increments();
|
||||
table.string('path');
|
||||
table.string('method');
|
||||
table.string('operation');
|
||||
table.string('params');
|
||||
table.text('headers');
|
||||
table.text('body');
|
||||
table.text('response');
|
||||
table.text('comments');
|
||||
table.timestamps(true, true);
|
||||
})
|
||||
},
|
||||
async down(knex) {
|
||||
await knex.schema.dropTable('nc_log')
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -37,7 +37,6 @@ import {RestApiBuilder} from "../rest/RestApiBuilder";
|
||||
import RestAuthCtrl from "../rest/RestAuthCtrlEE";
|
||||
import {packageVersion} from 'nc-help';
|
||||
import NcMetaIO, {META_TABLES} from "./NcMetaIO";
|
||||
// import NcConnectionMgr from "../common/NcConnectionMgr";
|
||||
|
||||
const XC_PLUGIN_DET = 'XC_PLUGIN_DET';
|
||||
|
||||
@@ -57,7 +56,6 @@ export default class NcMetaMgr {
|
||||
protected projectMgr: any;
|
||||
// @ts-ignore
|
||||
protected isEe = false;
|
||||
4
|
||||
|
||||
constructor(app: Noco, config: NcConfig, xcMeta: NcMetaIO) {
|
||||
this.app = app;
|
||||
@@ -212,20 +210,20 @@ export default class NcMetaMgr {
|
||||
|
||||
let projectHasAdmin = false;
|
||||
projectHasAdmin = !!(await knex('xc_users').first())
|
||||
|
||||
return res.json({
|
||||
authType: 'jwt',
|
||||
projectHasAdmin,
|
||||
firstUser: !projectHasAdmin,
|
||||
projectHasDb,
|
||||
type: this.config.type,
|
||||
env: this.config.workingEnv,
|
||||
googleAuthEnabled: !!(process.env.NC_GOOGLE_CLIENT_ID && process.env.NC_GOOGLE_CLIENT_SECRET),
|
||||
githubAuthEnabled: !!(process.env.NC_GITHUB_CLIENT_ID && process.env.NC_GITHUB_CLIENT_SECRET),
|
||||
oneClick: !!process.env.NC_ONE_CLICK,
|
||||
connectToExternalDB: !process.env.NC_CONNECT_TO_EXTERNAL_DB_DISABLED,
|
||||
version: packageVersion
|
||||
})
|
||||
const result = {
|
||||
authType: 'jwt',
|
||||
projectHasAdmin,
|
||||
firstUser: !projectHasAdmin,
|
||||
projectHasDb,
|
||||
type: this.config.type,
|
||||
env: this.config.workingEnv,
|
||||
googleAuthEnabled: !!(process.env.NC_GOOGLE_CLIENT_ID && process.env.NC_GOOGLE_CLIENT_SECRET),
|
||||
githubAuthEnabled: !!(process.env.NC_GITHUB_CLIENT_ID && process.env.NC_GITHUB_CLIENT_SECRET),
|
||||
oneClick: !!process.env.NC_ONE_CLICK,
|
||||
connectToExternalDB: !process.env.NC_CONNECT_TO_EXTERNAL_DB_DISABLED,
|
||||
version: packageVersion
|
||||
};
|
||||
return res.json(result)
|
||||
}
|
||||
if (this.config.auth.masterKey) {
|
||||
return res.json({
|
||||
@@ -292,6 +290,7 @@ export default class NcMetaMgr {
|
||||
return res.status(400).json({msg: e.message})
|
||||
}
|
||||
|
||||
|
||||
if (this.listener) {
|
||||
await this.listener({
|
||||
req: req.body,
|
||||
@@ -303,6 +302,8 @@ export default class NcMetaMgr {
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
return res.json(result);
|
||||
}
|
||||
|
||||
@@ -1019,6 +1020,7 @@ export default class NcMetaMgr {
|
||||
} catch (e) {
|
||||
return next(e);
|
||||
}
|
||||
|
||||
res.json(result);
|
||||
}
|
||||
|
||||
@@ -1496,7 +1498,6 @@ export default class NcMetaMgr {
|
||||
default:
|
||||
return next();
|
||||
}
|
||||
|
||||
if (this.listener) {
|
||||
await this.listener({
|
||||
user: req.user,
|
||||
|
||||
Reference in New Issue
Block a user