Commit b8f2a5f7 authored by Eirik Alvær's avatar Eirik Alvær

"userId" is now being logged from request object. Refs...

"userId" is now being logged from request object. Refs https://gitlab.nsd.no/raird/stack/issues/227#note_21824
Added support for setting default values. This simplifies logging of serviceStack among other things. Refs https://gitlab.nsd.no/nsd-commons/archive-guide-service/issues/2
Adds tests. Fixes #3.
parent c3b4e790
Pipeline #26151 passed with stage
in 22 seconds
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "attach",
"name": "Attach",
"port": 9229
}
]
}
\ No newline at end of file
This diff is collapsed.
{
"name": "@nsd/log-schema-node",
"version": "3.2.1",
"version": "3.3.0",
"main": "lib/index.js",
"types": "lib/index",
"scripts": {
"build": "tsc"
"clean": "tsc --build --clean",
"build": "tsc",
"build-watch": "tsc --watch",
"test": "lab lib/test --timeout 30000 --leaks",
"test-debug": "node --inspect-brk node_modules/.bin/lab lib/test --timeout 0"
},
"repository": "git@gitlab.nsd.uib.no:nsd-commons/log-schema-node.git",
"author": "Snorre Magnus Davøen <snorre.davoen@nsd.uib.no>",
"license": "See LICENSE",
"dependencies": {
"cookie": "0.4.0",
"dotenv": "6.2.0",
"express": "4.16.4",
"jsonschema": "1.2.4",
"jwt-decode": "2.2.0",
"lodash": "4.17.15"
},
"devDependencies": {
"@types/capture-console": "1.0.0",
"@types/code": "4.0.5",
"@types/cookie": "0.3.3",
"@types/express": "4.16.1",
"@types/lab": "11.1.0",
"@types/lodash": "4.14.121",
"capture-console": "1.0.1",
"code": "5.2.4",
"jayschema": "^0.3.1",
"json-schema-to-typescript": "^4.2.0",
"jsonwebtoken": "8.5.1",
"lab": "18.0.2",
"tslint": "^5.2.0",
"typescript": "3.3.3333"
},
......
import { LogSchema, schema } from "./index";
import Cookie = require("cookie");
import Express = require("express");
import Http = require("http");
import JsonSchema = require("jsonschema");
import JwtDecode = require("jwt-decode");
import _ = require("lodash");
const maxStringSize = 1000;
......@@ -66,6 +68,23 @@ function extractHeaders(headers: Http.IncomingHttpHeaders | Http.OutgoingHttpHea
return res;
}
function getUserId(req: Express.Request) {
let auth = _.get(req.headers, "authorization");
if (!auth) {
const cookie = _.get(req.headers, "cookie");
if (cookie) {
const cookies = Cookie.parse(cookie);
auth = _.get(cookies, "authorization")
}
}
if (auth) {
const res = JwtDecode(auth);
if (res) {
return res.sub;
}
}
}
function getLogData(input: LogInput): LogSchema {
let res = _.cloneDeep(defaultValues) as LogInput;
......@@ -89,11 +108,16 @@ function getLogData(input: LogInput): LogSchema {
query: req.query,
path: req.params
}
if (input.logRequestPayload && res.request.payload) {
if (input.logRequestPayload && req.body) {
res.request.payload = stringify(req.body, input.maxStringSize);
}
res.url = req.url;
res.xRequestId = _.get(req, "id");
res.xRequestId = _.get(req, "id");
const userId = getUserId(req);
if (userId) {
res.userId = userId;
}
}
const response = input.response;
if (response) {
......@@ -190,4 +214,8 @@ export function middleware(req: Express.Request, res: Express.Response, next: Ex
}
next();
}
export function setDefaultValue(data: PartialLogSchema) {
_.merge(defaultValues, data);
}
\ No newline at end of file
import Jwt = require("jsonwebtoken");
const privateKey = `-----BEGIN RSA PRIVATE KEY-----
MIICWwIBAAKBgQDdlatRjRjogo3WojgGHFHYLugdUWAY9iR3fy4arWNA1KoS8kV
w33cJibXr8bvwUAUparCwlvdbH6dvEOfou0/gCFQsHUfQrSDv+MuSUMAe8jzKE4
qW+jK+xQU9a03GUnKHkkle+Q0pX/g6jXZ7r1/xAK5Do2kQ+X5xK9cipRgEKwIDA
QABAoGAD+onAtVye4ic7VR7V50DF9bOnwRwNXrARcDhq9LWNRrRGElESYYTQ6Eb
atXS3MCyjjX2eMhu/aF5YhXBwkppwxg+EOmXeh+MzL7Zh284OuPbkglAaGhV9bb
6/5CpuGb1esyPbYW+Ty2PC0GSZfIXkXs76jXAu9TOBvD0ybc2YlkCQQDywg2R/7
t3Q2OE2+yo382CLJdrlSLVROWKwb4tb2PjhY4XAwV8d1vy0RenxTB+K5Mu57uVS
THtrMK0GAtFr833AkEA6avx20OHo61Yela/4k5kQDtjEf1N0LfI+BcWZtxsS3jD
M3i1Hp0KSu5rsCPb8acJo5RO26gGVrfAsDcIXKC+bQJAZZ2XIpsitLyPpuiMOvB
bzPavd4gY6Z8KWrfYzJoI/Q9FuBo6rKwl4BFoToD7WIUS+hpkagwWiz+6zLoX1d
bOZwJACmH5fSSjAkLRi54PKJ8TFUeOP15h9sQzydI8zJU+upvDEKZsZc/UhT/Sy
SDOxQ4G/523Y0sz/OZtSWcol/UMgQJALesy++GdvoIDLfJX5GBQpuFgFenRiRDa
bxrE9MNUZ2aPFaFp+DyAe+b4nDwuJaW2LURbr8AEZga7oQj0uYxcYw==
-----END RSA PRIVATE KEY-----`;
const claims = {
sub: "user-id-123",
aud: ["log-schema-node"]
}
export = Jwt.sign(
claims,
privateKey,
{
algorithm: "RS256",
header: {
alg: "RS256",
kid: "123"
}
}
);
\ No newline at end of file
import _ = require("lodash");
import Capcon = require("capture-console");
import Code = require("code");
import Express = require("express");
import {ExpressLogger as Logger, LogSchema} from ".."
import JwtToken = require("./JwtToken");
import Lab = require("lab");
const expect = Code.expect;
const lab = exports.lab = Lab.script();
type PartialRequest = Partial<Express.Request>
function getRequest(req: PartialRequest): Express.Request {
let result: PartialRequest = {
hostname: "localhost",
method: "get",
connection: <any> {
localPort: 80,
},
headers: {},
query: {},
params: {},
url: "http://localhost",
body: ""
}
_.merge(result, req);
return result as Express.Request;
}
lab.experiment("log-schema-node", () => {
lab.before(() => {
process.env.NODE_ENV = "production";
});
lab.test("hello lab", () => {
const n = 10;
expect(n).to.equal(10);
});
lab.test("simple-info", () => {
const logged = Capcon.captureStdout(() => {
Logger.info({
message: "simple-info"
});
});
const obj: LogSchema = JSON.parse(logged);
expect(obj.message).to.equal("simple-info");
expect(obj.levelName).to.equal("INFO");
});
lab.test("user-id-header", () => {
const authorization = "Bearer " + JwtToken;
const req = getRequest({
headers: { authorization }
});
const logged = Capcon.captureStdout(() => {
Logger.info({
message: "user-id-header",
req
});
});
const obj: LogSchema = JSON.parse(logged);
expect(obj.message).to.equal("user-id-header");
expect(obj.userId).to.equal("user-id-123");
});
lab.test("user-id-cookie", () => {
const cookie = "authorization=" + JwtToken;
const req = getRequest({
headers: { cookie }
});
const logged = Capcon.captureStdout(() => {
Logger.info({
message: "user-id-header",
req
});
});
const obj: LogSchema = JSON.parse(logged);
expect(obj.message).to.equal("user-id-header");
expect(obj.userId).to.equal("user-id-123");
});
lab.test("default-serviceStack", () => {
Logger.setDefaultValue({ serviceStack: "TEST"});
const logged = Capcon.captureStdout(() => {
Logger.info({
message: "default-serviceStack"
});
});
const obj: LogSchema = JSON.parse(logged);
expect(obj.message).to.equal("default-serviceStack");
expect(obj.serviceStack).to.equal("TEST");
})
});
\ No newline at end of file
......@@ -2,8 +2,10 @@
"compilerOptions": {
"declaration": true,
"outDir": "lib",
"rootDir": "src",
"target": "es6",
"module": "commonjs"
"module": "commonjs",
"sourceMap": true
},
"exclude": [
"lib",
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment