@coe-sys/pims
v2.0.0
Published
The shared NestJS support library behind the PIMS gateways: API-key auth, the proxy middlewares, request/response logging with redaction, and the process safety nets.
Readme
@coe-sys/pims
The shared NestJS support library behind the PIMS gateways: API-key auth, the proxy middlewares, request/response logging with redaction, and the process safety nets.
Install
npm install @coe-sys/pimsRequires NestJS ^11 and Node >= 20. The @nestjs/* packages are peer
dependencies, so npm will refuse the install on NestJS 10 rather than nest a
second framework copy. Do not force it onto NestJS 10 — a root-entry import
then fails to boot with a MongooseCoreModule/ModuleRef error. Services still
on 10 can use @coe-sys/pims/core (below) in the meantime; see the 0.8.0 notes
in CHANGELOG.md.
Quickstart
import { Module } from '@nestjs/common';
import { PimsModule } from '@coe-sys/pims';
@Module({ imports: [PimsModule] })
export class AppModule {}PimsModule needs MONGODB_URI in the environment, and reads API_LOG,
KAFKA_LOG, GATEWAY_HOST and GATEWAY_KEY for the logging paths. It exports
PimsService, LogService, ApiKeysService, ResponseInterceptorService and
ApiLogInterceptor.
TLS verification for proxied upstreams
Every proxy middleware verifies its upstream's certificate unless the matching
flag says otherwise. The flags are three-valued: 1 turns verification off, 0
turns it on, and any other value — an unset flag included — leaves the
upstream's own default in place.
| Flag | Upstream | Default |
| --- | --- | --- |
| PROXY_TLS_INSECURE | PROXY_HOST | verifies |
| PMS_TLS_INSECURE | PMS_HOST | verifies |
| KSQL_TLS_INSECURE | KSQL_HOST | verifies |
| FS_TLS_INSECURE | FS_HOST | verifies |
| COUPON_TLS_INSECURE | COUPON_HOST | verifies |
| FINEDAY_TLS_INSECURE | FINEDAY_HOST | skips |
FINEDAY_HOST sits on the internal network, which issues no certificate a trust
store accepts. Verification there fails every call, so each consumer ended up
copying the same flag into its own environment; the default carries it instead.
Set FINEDAY_TLS_INSECURE=0 in any deployment whose fineday host presents a
certificate you do want verified.
Whenever verification is off the library logs a warning naming the flag, the value that turned it off, and the way back — a skipped check should not be silent.
Customising what gets logged
LOG_POLICY decides which requests are logged and how they are redacted. The
default (DefaultLogPolicy) excludes credential and payment routes and masks
sensitive headers. Replace it through forRoot:
import { Module } from '@nestjs/common';
import { PimsModule, DefaultLogPolicy, LogRequestContext } from '@coe-sys/pims';
/** Keep payment traffic, but store the response as an audit marker only. */
class PaymentAuditLogPolicy extends DefaultLogPolicy {
shouldLog(ctx: LogRequestContext): boolean {
return /\/payment\//i.test(ctx.uri) || super.shouldLog(ctx);
}
redactResponse(): unknown {
return '[AUDITED]';
}
}
@Module({
imports: [PimsModule.forRoot({ logPolicy: PaymentAuditLogPolicy })],
})
export class AppModule {}Use forRoot — not providers: [{ provide: LOG_POLICY, ... }] in your own
module. Nest resolves providers per module, so a provider declared in your
AppModule cannot shadow the one inside PimsModule: your APP_INTERCEPTOR-built
ApiLogInterceptor would use your policy while the library's own writers kept
the default, redacting the same request two different ways. forRoot replaces
the provider inside PimsModule, which reaches all three writers.
Policy methods must be synchronous and must not throw — they run on the proxy response path.
@coe-sys/pims/core
The framework-free subset: no @nestjs/*, no mongoose, no
http-proxy-middleware is pulled into the process. Importable from any NestJS
version, or from an application that uses no framework at all.
import { shouldLogUri, redactBody, hashApiKey, convertKsqlResult } from '@coe-sys/pims/core';Process safety nets
Node terminates on an unhandled rejection or uncaught exception by default, and this library floats promises that reach Mongo. Install the nets once at bootstrap so a Mongo hiccup becomes a logged incident instead of downtime:
import { installProcessSafetyNets } from '@coe-sys/pims';
installProcessSafetyNets();Pair it with a container restart policy and alerting on those log lines.
Changelog
See CHANGELOG.md — including the breaking changes in 1.0.0.
