Mask sensitive data when logging based on the Client's configured rules
The following tools need to be installed:
Capability | Module |
---|---|
Dependence Framework | typescript adds optional types to JavaScript that support tools for large-scale JavaScript applications |
Coding Standard | eslint statically analyzes your code to quickly find and fix problems based on opt-in rules, prettier an opinionated code formatter to build and enforce a style guide on save, eslint-config-prettier to turns off all rules that are unnecessary or might conflict with Prettier. |
Testing Framework | Jest a delightful JavaScript Testing Framework with a focus on simplicity. |
Useful Links | npmtrends Compare package download counts over time, act run your GitHub Actions locally, Actionlint static checker for GitHub Actions workflow files,TypeDoc is a documentation generator for TypeScript |
git clone git@github.com:myria-libs/logger-mask-sensitive-js.git
# install dependencies
npm install | yarn install
# run build
npm run build | yarn build
# check lint's rules
npm run lint | yarn lint
# check lint's rules and try to fix
npm run lint:fix | yarn lint:fix
# format your code
npm run prettier:format | yarn prettier:format
npm test | yarn test
npm i @myria/logger-mask-sensitive-js
import { maskSensitiveData } from '@myria/logger-mask-sensitive-js';
import { createLogger, format, transports } from 'winston';
// Define rules
const sensitivityRules = [
{ key: 'ssn', pattern: /\d{3}-\d{2}-\d{4}/, replacement: '***-**-****' },
{ key: 'creditCard', pattern: /\d{16}/, replacement: '**** **** **** ****' },
{ key: 'phoneNumber', pattern: /\d{3}-\d{3}-\d{4}/, replacement: '***-***-****' },
{ key: 'email', pattern: /\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b/, replacement: '****@****.com' }
];
// Create logger from a logger library e.g. winston and custom format based on the built-in function maskSensitiveData
function create(rules, level) {
const customFormat = format.printf(({ level, message, timestamp }) => {
let maskedMessage;
try {
const parsedMessage = JSON.parse(message);
maskedMessage = maskSensitiveData(rules, parsedMessage);
} catch (e) {
maskedMessage = message;
}
return `${timestamp} ${level}: ${JSON.stringify(maskedMessage)}`;
});
const logger = createLogger({
level,
format: format.combine(
format.timestamp(),
format.colorize(),
customFormat
),
transports: [
new transports.Console({
format: customFormat,
}),
],
});
return logger;
}
const sharedLogger = create(sensitivityRules, 'debug');
// Example logging info in processing payment without worrying about leaking sensitive info
function processPayment() {
const message = {
userId: 'user123',
ssn: '123-45-6789', // Social Security Number
creditCard: '1234567812345678', // Credit Card Number
phoneNumber: '123-456-7890', // Phone Number
email: 'user@example.com', // Email
transactionDetails: 'Payment for invoice #12345'
}
sharedLogger.info(JSON.stringify(message));
}
Full E2E integration reference in the example/src/index.js. Should be straightforward
- We use the git rebase strategy to keep tracking meaningful commit message. Help to enable rebase when pull
$ git config --local pull.rebase true
- Follow TypeScript Style Guide Google
- Follow Best-Practices in coding:
- Clean code make team happy
- Return early make code safer and use resource Efficiency
- Truthy & Falsy make code shorter
- SOLID Principles make clean code
- DRY & KISS avoid redundancy and make your code as simple as possible
- Make buildable commit and pull latest code from
main
branch frequently - Follow the Semantic Versioning once we are ready for release
- Use readable commit message karma
/‾‾‾‾‾‾‾‾
🔔 < Ring! Please use semantic commit messages
\________
<type>(<scope>): ([issue number]) <subject>
│ │ | │
| | | └─> subject in present tense. Not capitalized. No period at the end.
| | |
│ │ └─> Issue number (optional): Jira Ticket or Issue number
│ │
│ └─> Scope (optional): eg. Articles, Profile, Core
│
└─> Type: chore, docs, feat, fix, refactor, style, ci, perf, build, or test.