mirror of
https://github.com/nocodb/nocodb.git
synced 2026-04-25 06:45:41 +00:00
1
.gitignore
vendored
1
.gitignore
vendored
@@ -78,3 +78,4 @@ mongod
|
|||||||
|
|
||||||
.history
|
.history
|
||||||
/packages/nocodb/docker/main.js.LICENSE.txt
|
/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,
|
info,
|
||||||
aggregatedInfo: {
|
aggregatedInfo: {
|
||||||
list: this.apiInfInfoList,
|
list: this.apiInfInfoList,
|
||||||
aggregated: this.aggregatedApiInfo
|
aggregated: this.aggregatedApiInfo
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
|
||||||
|
res.json(result);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -32,6 +32,8 @@ import {RestApiBuilder} from "./rest/RestApiBuilder";
|
|||||||
import RestAuthCtrlCE from "./rest/RestAuthCtrl";
|
import RestAuthCtrlCE from "./rest/RestAuthCtrl";
|
||||||
import RestAuthCtrlEE from "./rest/RestAuthCtrlEE";
|
import RestAuthCtrlEE from "./rest/RestAuthCtrlEE";
|
||||||
import mkdirp from 'mkdirp';
|
import mkdirp from 'mkdirp';
|
||||||
|
import MetaAPILogger from "./meta/MetaAPILogger";
|
||||||
|
|
||||||
const log = debug('nc:app');
|
const log = debug('nc:app');
|
||||||
require('dotenv').config();
|
require('dotenv').config();
|
||||||
|
|
||||||
@@ -177,7 +179,7 @@ export default class Noco {
|
|||||||
/******************* Middlewares : start *******************/
|
/******************* Middlewares : start *******************/
|
||||||
this.router.use((req: any, _res, next) => {
|
this.router.use((req: any, _res, next) => {
|
||||||
req.nc = this.requestContext;
|
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;
|
req.ncFullUrl = req.protocol + '://' + req.get('host') + req.originalUrl;
|
||||||
next();
|
next();
|
||||||
});
|
});
|
||||||
@@ -205,6 +207,7 @@ export default class Noco {
|
|||||||
req.ncProjectId = req.ncProjectId || req.params.project_id;
|
req.ncProjectId = req.ncProjectId || req.params.project_id;
|
||||||
next();
|
next();
|
||||||
})
|
})
|
||||||
|
this.router.use(MetaAPILogger.mw);
|
||||||
|
|
||||||
/******************* Middlewares : end *******************/
|
/******************* 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 RestAuthCtrl from "../rest/RestAuthCtrlEE";
|
||||||
import {packageVersion} from 'nc-help';
|
import {packageVersion} from 'nc-help';
|
||||||
import NcMetaIO, {META_TABLES} from "./NcMetaIO";
|
import NcMetaIO, {META_TABLES} from "./NcMetaIO";
|
||||||
// import NcConnectionMgr from "../common/NcConnectionMgr";
|
|
||||||
|
|
||||||
const XC_PLUGIN_DET = 'XC_PLUGIN_DET';
|
const XC_PLUGIN_DET = 'XC_PLUGIN_DET';
|
||||||
|
|
||||||
@@ -57,7 +56,6 @@ export default class NcMetaMgr {
|
|||||||
protected projectMgr: any;
|
protected projectMgr: any;
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
protected isEe = false;
|
protected isEe = false;
|
||||||
4
|
|
||||||
|
|
||||||
constructor(app: Noco, config: NcConfig, xcMeta: NcMetaIO) {
|
constructor(app: Noco, config: NcConfig, xcMeta: NcMetaIO) {
|
||||||
this.app = app;
|
this.app = app;
|
||||||
@@ -212,20 +210,20 @@ export default class NcMetaMgr {
|
|||||||
|
|
||||||
let projectHasAdmin = false;
|
let projectHasAdmin = false;
|
||||||
projectHasAdmin = !!(await knex('xc_users').first())
|
projectHasAdmin = !!(await knex('xc_users').first())
|
||||||
|
const result = {
|
||||||
return res.json({
|
authType: 'jwt',
|
||||||
authType: 'jwt',
|
projectHasAdmin,
|
||||||
projectHasAdmin,
|
firstUser: !projectHasAdmin,
|
||||||
firstUser: !projectHasAdmin,
|
projectHasDb,
|
||||||
projectHasDb,
|
type: this.config.type,
|
||||||
type: this.config.type,
|
env: this.config.workingEnv,
|
||||||
env: this.config.workingEnv,
|
googleAuthEnabled: !!(process.env.NC_GOOGLE_CLIENT_ID && process.env.NC_GOOGLE_CLIENT_SECRET),
|
||||||
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),
|
||||||
githubAuthEnabled: !!(process.env.NC_GITHUB_CLIENT_ID && process.env.NC_GITHUB_CLIENT_SECRET),
|
oneClick: !!process.env.NC_ONE_CLICK,
|
||||||
oneClick: !!process.env.NC_ONE_CLICK,
|
connectToExternalDB: !process.env.NC_CONNECT_TO_EXTERNAL_DB_DISABLED,
|
||||||
connectToExternalDB: !process.env.NC_CONNECT_TO_EXTERNAL_DB_DISABLED,
|
version: packageVersion
|
||||||
version: packageVersion
|
};
|
||||||
})
|
return res.json(result)
|
||||||
}
|
}
|
||||||
if (this.config.auth.masterKey) {
|
if (this.config.auth.masterKey) {
|
||||||
return res.json({
|
return res.json({
|
||||||
@@ -292,6 +290,7 @@ export default class NcMetaMgr {
|
|||||||
return res.status(400).json({msg: e.message})
|
return res.status(400).json({msg: e.message})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (this.listener) {
|
if (this.listener) {
|
||||||
await this.listener({
|
await this.listener({
|
||||||
req: req.body,
|
req: req.body,
|
||||||
@@ -303,6 +302,8 @@ export default class NcMetaMgr {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return res.json(result);
|
return res.json(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1019,6 +1020,7 @@ export default class NcMetaMgr {
|
|||||||
} catch (e) {
|
} catch (e) {
|
||||||
return next(e);
|
return next(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
res.json(result);
|
res.json(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1496,7 +1498,6 @@ export default class NcMetaMgr {
|
|||||||
default:
|
default:
|
||||||
return next();
|
return next();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.listener) {
|
if (this.listener) {
|
||||||
await this.listener({
|
await this.listener({
|
||||||
user: req.user,
|
user: req.user,
|
||||||
|
|||||||
Reference in New Issue
Block a user