mirror of
https://github.com/Ride-The-Lightning/RTL.git
synced 2026-08-13 12:33:07 +02:00
Replace deprecated csurf with csrf-csrf
csurf has been deprecated since 2022 and pins an old cookie release with a known advisory; npm's only fix is a downgrade (issue #1634, item 2). csrf-csrf v4 implements the same double-submit-cookie pattern with an HMAC-signed, session-bound token keyed on the existing boot secret (common.secret_key). The frontend contract is unchanged: the token still arrives via the XSRF-TOKEN cookie/header and is echoed as x-xsrf-token (all token sources csurf accepted are still read), the signed cookie keeps the _csrf name (now httpOnly, secure:false to match the session cookie on plain-HTTP deployments), doubleCsrfProtection attaches req.csrfToken so app.ts keeps working, and the error code is EBADCSRFTOKEN - already handled in app.ts. The websocket upgrade check in authCheck.ts now routes through the shared middleware; upgrade requests are GETs, so its pass-through semantics are unchanged. One fix this surfaced: app.ts called req.csrfToken() twice (cookie and header). Under csurf every token validated against a stable secret; under csrf-csrf each first-visit call mints a new token, desyncing the XSRF-TOKEN cookie from the _csrf cookie it must equal. The token is now generated once per request. Tokens are session-bound, so a token stolen from one session no longer validates in another - a check csurf's cookie mode did not perform. Production npm audit drops from 6 low findings to 4, all in the crypto-browserify/elliptic chain tracked in #1634. Verified against the docker regtest fixture: both API suites (43 checks across LND, CLN and Eclair) plus a dedicated CSRF battery - valid-token auth, missing token 403, garbage token 403, cross-session replay 403, token stability across requests, the XSRF-TOKEN response header for Quickpay, and the websocket handshake. Lint and build are clean.
This commit is contained in:
parent
6e61d1b759
commit
e617fbb561
9 changed files with 114 additions and 110 deletions
|
|
@ -37,8 +37,12 @@ export class ExpressApplication {
|
|||
this.app.use(this.common.baseHref + '/api/ecl', eclRoutes);
|
||||
this.app.use(this.common.baseHref, express.static(join(this.directoryName, '../..', 'frontend')));
|
||||
this.app.use((req, res, next) => {
|
||||
res.cookie('XSRF-TOKEN', req.csrfToken ? req.csrfToken() : (req.cookies && req.cookies._csrf) ? req.cookies._csrf : ''); // RTL Angular Frontend
|
||||
res.setHeader('XSRF-TOKEN', req.csrfToken ? req.csrfToken() : (req.cookies && req.cookies._csrf) ? req.cookies._csrf : ''); // RTL Quickpay JQuery
|
||||
// Generate the token once per request: with csrf-csrf every call mints a
|
||||
// new token on a first visit, so calling twice would desync the cookie
|
||||
// from the header and the _csrf cookie it must match.
|
||||
const csrfToken = req.csrfToken ? req.csrfToken() : (req.cookies && req.cookies._csrf) ? req.cookies._csrf : '';
|
||||
res.cookie('XSRF-TOKEN', csrfToken); // RTL Angular Frontend
|
||||
res.setHeader('XSRF-TOKEN', csrfToken); // RTL Quickpay JQuery
|
||||
res.sendFile(join(this.directoryName, '../..', 'frontend', 'index.html'));
|
||||
});
|
||||
this.app.use((err, req, res, next) => {
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
import jwt from 'jsonwebtoken';
|
||||
import csurf from 'csurf/index.js';
|
||||
import CSRF from './csrf.js';
|
||||
import { Common } from './common.js';
|
||||
import { Logger } from './logger.js';
|
||||
const common = Common;
|
||||
const logger = Logger;
|
||||
const csurfProtection = csurf({ cookie: true });
|
||||
const csurfProtection = CSRF.csrfProtection;
|
||||
export const isAuthenticated = (req, res, next) => {
|
||||
try {
|
||||
const token = req.headers.authorization.split(' ')[1];
|
||||
|
|
|
|||
|
|
@ -1,11 +1,26 @@
|
|||
import csurf from 'csurf/index.js';
|
||||
import { doubleCsrf } from 'csrf-csrf';
|
||||
import { Logger } from './logger.js';
|
||||
import { Common } from './common.js';
|
||||
class CSRF {
|
||||
constructor() {
|
||||
this.csrfProtection = csurf({ cookie: true });
|
||||
this.logger = Logger;
|
||||
this.common = Common;
|
||||
// Signed double-submit-cookie protection (replaces the deprecated csurf).
|
||||
// The signed token lives in the httpOnly '_csrf' cookie; the client echoes
|
||||
// the same token (read from the XSRF-TOKEN cookie set in app.ts) in a
|
||||
// header. The cookie is not secure-only because RTL commonly serves plain
|
||||
// HTTP (matching the session cookie); token sources match what csurf
|
||||
// accepted. The error code EBADCSRFTOKEN is handled in app.ts.
|
||||
this.doubleCsrfUtilities = doubleCsrf({
|
||||
getSecret: () => this.common.secret_key,
|
||||
getSessionIdentifier: (req) => (req.session ? req.session.id : ''),
|
||||
cookieName: '_csrf',
|
||||
cookieOptions: { sameSite: 'strict', path: '/', secure: false, httpOnly: true },
|
||||
getCsrfTokenFromRequest: (req) => (req.body && req.body._csrf) || (req.query && req.query._csrf) ||
|
||||
req.headers['csrf-token'] || req.headers['xsrf-token'] ||
|
||||
req.headers['x-csrf-token'] || req.headers['x-xsrf-token']
|
||||
});
|
||||
this.csrfProtection = this.doubleCsrfUtilities.doubleCsrfProtection;
|
||||
}
|
||||
mount(app) {
|
||||
this.logger.log({ selectedNode: this.common.selectedNode, level: 'INFO', fileName: 'CSRF', msg: 'Setting up CSRF..' });
|
||||
|
|
|
|||
135
package-lock.json
generated
135
package-lock.json
generated
|
|
@ -18,7 +18,7 @@
|
|||
"buffer": "6.0.3",
|
||||
"cookie-parser": "1.4.7",
|
||||
"crypto-browserify": "3.12.1",
|
||||
"csurf": "1.11.0",
|
||||
"csrf-csrf": "4.0.3",
|
||||
"express": "5.2.1",
|
||||
"express-session": "1.18.2",
|
||||
"hocon-parser": "1.0.1",
|
||||
|
|
@ -9274,18 +9274,48 @@
|
|||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/csrf": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/csrf/-/csrf-3.1.0.tgz",
|
||||
"integrity": "sha512-uTqEnCvWRk042asU6JtapDTcJeeailFy4ydOQS28bj1hcLnYRiqi8SsD2jS412AY1I/4qdOwWZun774iqywf9w==",
|
||||
"node_modules/csrf-csrf": {
|
||||
"version": "4.0.3",
|
||||
"resolved": "https://registry.npmjs.org/csrf-csrf/-/csrf-csrf-4.0.3.tgz",
|
||||
"integrity": "sha512-DaygOzelL4Qo1pHwI9LPyZL+X2456/OzpT596kNeZGiTSqKVDOk/9PPJ+FjzZacjMUEusOHw3WJKe1RW4iUhrw==",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"http-errors": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/csrf-csrf/node_modules/http-errors": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz",
|
||||
"integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"rndm": "1.2.0",
|
||||
"tsscmp": "1.0.6",
|
||||
"uid-safe": "2.1.5"
|
||||
"depd": "~2.0.0",
|
||||
"inherits": "~2.0.4",
|
||||
"setprototypeof": "~1.2.0",
|
||||
"statuses": "~2.0.2",
|
||||
"toidentifier": "~1.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/express"
|
||||
}
|
||||
},
|
||||
"node_modules/csrf-csrf/node_modules/setprototypeof": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
|
||||
"integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==",
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/csrf-csrf/node_modules/toidentifier": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
|
||||
"integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/css-loader": {
|
||||
|
|
@ -9367,31 +9397,6 @@
|
|||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/csurf": {
|
||||
"version": "1.11.0",
|
||||
"resolved": "https://registry.npmjs.org/csurf/-/csurf-1.11.0.tgz",
|
||||
"integrity": "sha512-UCtehyEExKTxgiu8UHdGvHj4tnpE/Qctue03Giq5gPgMQ9cg/ciod5blZQ5a4uCEenNQjxyGuzygLdKUmee/bQ==",
|
||||
"deprecated": "This package is archived and no longer maintained. For support, visit https://github.com/expressjs/express/discussions",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"cookie": "0.4.0",
|
||||
"cookie-signature": "1.0.6",
|
||||
"csrf": "3.1.0",
|
||||
"http-errors": "~1.7.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/csurf/node_modules/cookie": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz",
|
||||
"integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/custom-event": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/custom-event/-/custom-event-1.0.1.tgz",
|
||||
|
|
@ -11953,40 +11958,6 @@
|
|||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/http-errors": {
|
||||
"version": "1.7.3",
|
||||
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.3.tgz",
|
||||
"integrity": "sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"depd": "~1.1.2",
|
||||
"inherits": "2.0.4",
|
||||
"setprototypeof": "1.1.1",
|
||||
"statuses": ">= 1.5.0 < 2",
|
||||
"toidentifier": "1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/http-errors/node_modules/depd": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
|
||||
"integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/http-errors/node_modules/statuses": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
|
||||
"integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/http-parser-js": {
|
||||
"version": "0.5.10",
|
||||
"resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.10.tgz",
|
||||
|
|
@ -16995,12 +16966,6 @@
|
|||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/rndm": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/rndm/-/rndm-1.2.0.tgz",
|
||||
"integrity": "sha512-fJhQQI5tLrQvYIYFpOnFinzv9dwmR7hRnUz1XqP3OJ1jIweTNOd6aTO4jwQSgcBSFUB+/KHJxuGneime+FdzOw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/roboto-fontface": {
|
||||
"version": "0.10.0",
|
||||
"resolved": "https://registry.npmjs.org/roboto-fontface/-/roboto-fontface-0.10.0.tgz",
|
||||
|
|
@ -17661,12 +17626,6 @@
|
|||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/setprototypeof": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz",
|
||||
"integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==",
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/sha.js": {
|
||||
"version": "2.4.12",
|
||||
"resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.12.tgz",
|
||||
|
|
@ -18636,15 +18595,6 @@
|
|||
"node": ">=8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/toidentifier": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz",
|
||||
"integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/touch": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/touch/-/touch-3.1.1.tgz",
|
||||
|
|
@ -18769,15 +18719,6 @@
|
|||
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
|
||||
"license": "0BSD"
|
||||
},
|
||||
"node_modules/tsscmp": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/tsscmp/-/tsscmp-1.0.6.tgz",
|
||||
"integrity": "sha512-LxhtAkPDTkVCMQjt2h6eBVY28KCjikZqZfMcC15YBeNjkgUpdCfBu5HoiOTDu86v6smE8yOjyEktJ8hlbANHQA==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.6.x"
|
||||
}
|
||||
},
|
||||
"node_modules/tsyringe": {
|
||||
"version": "4.10.0",
|
||||
"resolved": "https://registry.npmjs.org/tsyringe/-/tsyringe-4.10.0.tgz",
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@
|
|||
"buffer": "6.0.3",
|
||||
"cookie-parser": "1.4.7",
|
||||
"crypto-browserify": "3.12.1",
|
||||
"csurf": "1.11.0",
|
||||
"csrf-csrf": "4.0.3",
|
||||
"express": "5.2.1",
|
||||
"express-session": "1.18.2",
|
||||
"hocon-parser": "1.0.1",
|
||||
|
|
|
|||
|
|
@ -174,6 +174,29 @@ this release should add its entry under the appropriate section below.
|
|||
from Core Lightning and Eclair, message sign/verify, channel backup to disk, bad-invoice
|
||||
and node-unreachable error mapping) plus a clean lint and both production builds.
|
||||
|
||||
- **Replace the deprecated `csurf` middleware with `csrf-csrf`**
|
||||
([#TBD](https://github.com/Ride-The-Lightning/RTL/pull/TBD), part of
|
||||
[#1634](https://github.com/Ride-The-Lightning/RTL/issues/1634)).
|
||||
`csurf` has been deprecated since 2022 and pins an old `cookie` release with a known
|
||||
advisory; npm's only offered "fix" is a downgrade. It is now replaced by the maintained
|
||||
`csrf-csrf` (v4), which implements the same double-submit-cookie pattern with an
|
||||
HMAC-signed, session-bound token keyed on RTL's existing boot secret. The frontend
|
||||
contract is unchanged — the token still arrives in the `XSRF-TOKEN` cookie/header and is
|
||||
echoed back as `x-xsrf-token` (all header/body/query token sources csurf accepted are
|
||||
still accepted), the signed token cookie keeps the `_csrf` name (now httpOnly), and the
|
||||
`EBADCSRFTOKEN` error path in `app.ts` applies as before, so no Angular or Quickpay
|
||||
changes were needed. One behavioral fix this surfaced: `app.ts` called `req.csrfToken()`
|
||||
twice (cookie + header) — harmless under csurf, but token-desyncing under csrf-csrf —
|
||||
and now generates the token once per request. Tokens are also now bound to the session,
|
||||
so a token stolen from one session no longer validates in another — a check csurf's
|
||||
cookie mode didn't perform (and the websocket upgrade check in `authCheck.ts` keeps its
|
||||
previous semantics). Production `npm audit` drops from 6 low findings to 4, all in the
|
||||
`crypto-browserify`/`elliptic` chain tracked in #1634. Verified against the docker
|
||||
regtest fixture: both API suites (43 checks across LND, Core Lightning and Eclair) plus
|
||||
a dedicated CSRF battery — valid-token auth, missing/garbage token → 403,
|
||||
cross-session token replay → 403, token stability, the `XSRF-TOKEN` response header for
|
||||
Quickpay, and the websocket handshake.
|
||||
|
||||
- **Rebuild the compiled CLN channels controller to match its source**
|
||||
([#1631](https://github.com/Ride-The-Lightning/RTL/pull/1631)).
|
||||
The #1606 fix updated `server/controllers/cln/channels.ts` to mirror `peer_connected` onto the
|
||||
|
|
|
|||
|
|
@ -59,8 +59,12 @@ export class ExpressApplication {
|
|||
this.app.use(this.common.baseHref + '/api/ecl', eclRoutes);
|
||||
this.app.use(this.common.baseHref, express.static(join(this.directoryName, '../..', 'frontend')));
|
||||
this.app.use((req: any, res, next) => {
|
||||
res.cookie('XSRF-TOKEN', req.csrfToken ? req.csrfToken() : (req.cookies && req.cookies._csrf) ? req.cookies._csrf : ''); // RTL Angular Frontend
|
||||
res.setHeader('XSRF-TOKEN', req.csrfToken ? req.csrfToken() : (req.cookies && req.cookies._csrf) ? req.cookies._csrf : ''); // RTL Quickpay JQuery
|
||||
// Generate the token once per request: with csrf-csrf every call mints a
|
||||
// new token on a first visit, so calling twice would desync the cookie
|
||||
// from the header and the _csrf cookie it must match.
|
||||
const csrfToken = req.csrfToken ? req.csrfToken() : (req.cookies && req.cookies._csrf) ? req.cookies._csrf : '';
|
||||
res.cookie('XSRF-TOKEN', csrfToken); // RTL Angular Frontend
|
||||
res.setHeader('XSRF-TOKEN', csrfToken); // RTL Quickpay JQuery
|
||||
res.sendFile(join(this.directoryName, '../..', 'frontend', 'index.html'));
|
||||
});
|
||||
this.app.use((err, req, res, next) => {
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
import jwt from 'jsonwebtoken';
|
||||
import csurf from 'csurf/index.js';
|
||||
import CSRF from './csrf.js';
|
||||
import { Common, CommonService } from './common.js';
|
||||
import { Logger, LoggerService } from './logger.js';
|
||||
|
||||
const common: CommonService = Common;
|
||||
const logger: LoggerService = Logger;
|
||||
const csurfProtection = csurf({ cookie: true });
|
||||
const csurfProtection = CSRF.csrfProtection;
|
||||
|
||||
export const isAuthenticated = (req, res, next) => {
|
||||
try {
|
||||
|
|
|
|||
|
|
@ -1,14 +1,31 @@
|
|||
import csurf from 'csurf/index.js';
|
||||
import { doubleCsrf } from 'csrf-csrf';
|
||||
import { Application } from 'express';
|
||||
import { Logger, LoggerService } from './logger.js';
|
||||
import { Common, CommonService } from './common.js';
|
||||
|
||||
class CSRF {
|
||||
|
||||
public csrfProtection = csurf({ cookie: true });
|
||||
public logger: LoggerService = Logger;
|
||||
public common: CommonService = Common;
|
||||
|
||||
// Signed double-submit-cookie protection (replaces the deprecated csurf).
|
||||
// The signed token lives in the httpOnly '_csrf' cookie; the client echoes
|
||||
// the same token (read from the XSRF-TOKEN cookie set in app.ts) in a
|
||||
// header. The cookie is not secure-only because RTL commonly serves plain
|
||||
// HTTP (matching the session cookie); token sources match what csurf
|
||||
// accepted. The error code EBADCSRFTOKEN is handled in app.ts.
|
||||
private doubleCsrfUtilities = doubleCsrf({
|
||||
getSecret: () => this.common.secret_key,
|
||||
getSessionIdentifier: (req: any) => (req.session ? req.session.id : ''),
|
||||
cookieName: '_csrf',
|
||||
cookieOptions: { sameSite: 'strict', path: '/', secure: false, httpOnly: true },
|
||||
getCsrfTokenFromRequest: (req: any) => (req.body && req.body._csrf) || (req.query && req.query._csrf) ||
|
||||
req.headers['csrf-token'] || req.headers['xsrf-token'] ||
|
||||
req.headers['x-csrf-token'] || req.headers['x-xsrf-token']
|
||||
});
|
||||
|
||||
public csrfProtection = this.doubleCsrfUtilities.doubleCsrfProtection;
|
||||
|
||||
public mount(app: Application): Application {
|
||||
this.logger.log({ selectedNode: this.common.selectedNode, level: 'INFO', fileName: 'CSRF', msg: 'Setting up CSRF..' });
|
||||
if (process.env.NODE_ENV !== 'development') {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue