nest
nest copied to clipboard
fix(core): merge req context with tenant payload in the request instance
PR Checklist
Please check if your PR fulfills the following requirements:
- [X] The commit message follows our guidelines: https://github.com/nestjs/nest/blob/master/CONTRIBUTING.md
- [X] Tests for the changes have been added (for bug fixes / features)
- [ ] Docs have been added / updated (for bug fixes / features)
PR Type
What kind of change does this PR introduce?
- [X] Bugfix
- [ ] Feature
- [ ] Code style update (formatting, local variables)
- [ ] Refactoring (no functional changes, no api changes)
- [ ] Build related changes
- [ ] CI related changes
- [ ] Other... Please describe:
What is the current behavior?
Doesn't create the request singleton with the contextId payload when the first request isn't to a durable tree.
Issue Number: #13477
What is the new behavior?
The payload generated by the contextIdFactory will be always merged to the request singleton, not matter if the the tree is durable or not.
Does this PR introduce a breaking change?
- [ ] Yes
- [X] No
Other information
I would like to know which tests should I updated, if needed.
Also the patch doesn't merge payload from the contextIdFactory in the request passed to canActivate method for AuthGuard and exception filter.
To patch the case above:
packages/core/router/router-explorer.ts lines 389 and 402
public createRequestScopedHandler(
instanceWrapper: InstanceWrapper,
requestMethod: RequestMethod,
moduleRef: Module,
moduleKey: string,
methodName: string,
) {
const { instance } = instanceWrapper;
const collection = moduleRef.controllers;
const isTreeDurable = instanceWrapper.isDependencyTreeDurable();
return async <TRequest extends Record<any, any>, TResponse>(
req: TRequest,
res: TResponse,
next: () => void,
) => {
try {
const contextId = this.getContextId(req, isTreeDurable);
const contextInstance = await this.injector.loadPerContext(
instance,
moduleRef,
collection,
contextId,
);
await this.createCallbackProxy(
contextInstance,
contextInstance[methodName],
methodName,
moduleKey,
requestMethod,
contextId,
instanceWrapper.id,
)(req, res, next);
} catch (err) {
let exceptionFilter = this.exceptionFiltersCache.get(
instance[methodName],
);
if (!exceptionFilter) {
exceptionFilter = this.exceptionsFilter.create(
instance,
instance[methodName],
moduleKey,
);
this.exceptionFiltersCache.set(instance[methodName], exceptionFilter);
}
const host = new ExecutionContextHost([req, res, next]);
exceptionFilter.next(err, host);
}
};
}
..., instanceWrapper.id, )(req, res, next);
should be replace by
..., instanceWrapper.id, )(Object.assign(req, contextId.payload), res, next);
and
const host = new ExecutionContextHost([req, res, next]);
should be replace by
const host = new ExecutionContextHost([Object.assign(req, contextId.payload), res, next]);