Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG] Body Validation not working as expected #2497

Closed
EinfachHans opened this issue Oct 31, 2023 · 16 comments · Fixed by #2504
Closed

[BUG] Body Validation not working as expected #2497

EinfachHans opened this issue Oct 31, 2023 · 16 comments · Fixed by #2504
Assignees

Comments

@EinfachHans
Copy link
Contributor

Describe the bug

I'm currently migrating a express application to Ts.ED. I used joi for the validation before and currently try to make AJV work, as i like the direct support & swagger integration.

I have a problem making the following work:

import { Integer, Required } from '@tsed/schema';

export class Test {
  @Integer()
  @Required()
  value: number;
}
@Post('/some-url')
async someFunction(@BodyParams() body: Test) {
  ...
}

Also writing @BodyParams(Test) ... does not work.

I don't find an exact documentation for this, except from Any model used on parameter and annotated with one of JsonSchema decorator will be validated with AJV. written here. So i guess my usage is correct and should work?

Also in my server.ts i have:

import '@tsed/ajv';

What does work for me is something like:

@Post('/some-url')
async someFunction(@BodyParams('value') @Integer() @Required value: number) {
  ...
}

but i would like to validate the whole body. Is this possible?

To Reproduce

Should be quite is to set up, see above.

Because this is also a kind of "should this be even possible" - issue, i dind't create an extra reproducable repo. If you need one, let me know.

Expected behavior

I would expect the full body to be validated correctly when used as described above. The request should ail with the ajv error.

Code snippets

No response

Repository URL example

No response

OS

macOS

Node version

18.17.1

Library version

7.41.2

Additional context

No response

@Romakita
Copy link
Collaborator

Hello @EinfachHans
This the base of tsed and it work as expected (there is a lot of integration test that cover these scenario).

have you generated the project with the CLI?

@EinfachHans
Copy link
Contributor Author

I did, but i already did a lot in my migration process. I will try to reproduce this in a cli starter project tomorrow and will follow up here.

@Romakita
Copy link
Collaborator

Ok ;)

@EinfachHans
Copy link
Contributor Author

Hey, can't reproduce this in a starter, will dig into whats going on in my project.

Thank you and i really appreciate this project, works great so far 👍🏼

Copy link

github-actions bot commented Nov 1, 2023

🎉 Are you happy?

If you appreciated the support, know that it is free and is carried out on personal time ;)

A support, even a little bit makes a difference for me and continues to bring you answers!

github opencollective

@Romakita
Copy link
Collaborator

Romakita commented Nov 1, 2023

Thanks @EinfachHans ;)
Tell me if you don’t see where the problem!

@EinfachHans
Copy link
Contributor Author

@Romakita not sure what change exactly, but make it worked now, thank you 👍🏼

Other question: I created a custom AJV keyword which also modifies the data. This seems to doesn't work with the current implementation of the AjvService.ts:

Here it always returns the input data, while the localData maybe has been adjusted by AJV:
https://github.com/tsedio/tsed/blob/c75fe924c512500f7a30eb7bbfcebbbbaf615353/packages/specs/ajv/src/services/AjvService.ts#L49C18-L49C18

Is this indeed? Is there any other configuration of stuff i'm missing?

@EinfachHans EinfachHans reopened this Nov 1, 2023
@Romakita
Copy link
Collaborator

Romakita commented Nov 1, 2023

@EinfachHans have you imported the new keyword class in server.ts using es6 import :

import "./keywords/MyKeyword"

@Romakita
Copy link
Collaborator

Romakita commented Nov 1, 2023

Haa sorry, your keyword modify the data?
Isn’t voluntary supported because ajv try to coerce data but this operation can occurs some bad behavior when the @tsed/json-mapper deserialize data.
But this problem maybe not occurs today, since the new json-mapper implementation.
I’ll take time too investigate.

@Romakita
Copy link
Collaborator

Romakita commented Nov 1, 2023

But to solve your issue, you can use @BeforeDeserialize decorator.

@EinfachHans
Copy link
Contributor Author

Yeah exactly, from my debugging (maybe it helps you):

  • AJV says in their documentation here:

    You can also define keywords that modify data.

  • My Keyword looks like this:

@Keyword({
  keyword: 'version',
  type: 'string'
})
export class VersionKeyword implements KeywordMethods {
  compile(): AjvDataValidateFunction {
    return (value: string, ctx: DataValidationCxt) => {
      const version = valid(value);
      if (version) {
        ctx.parentData[ctx.parentDataProperty] = version;
        return true;
      }
      return false;
    };
  }
}
  • Data Manipulation in tests works as expected
  • When debugging into the AJVService.ts i mentioned:
    • The schema is validated against a deep copy of the initial object (ref)
    • This new localData is correctly adjusted after the next line
    • But because the initial data is returned, the change happened to the localData is not passed to the final controller

@Romakita
Copy link
Collaborator

Romakita commented Nov 1, 2023

A simple test should be te return data and run integration test to see if it impact something.
I’m not on my computer. But you can try it locally, fork tsed, update code and run yarn test:integration

@EinfachHans
Copy link
Contributor Author

Okay, i just did. First: You seem to have a great test setup & coverage, really nice 👍🏼 Second: I adjusted the validate function of the AJVService to return the localValue after a successfully validation and the integration test passed

@Romakita
Copy link
Collaborator

Romakita commented Nov 1, 2023

Ok let’s go for the PR ;)

Copy link

github-actions bot commented Nov 2, 2023

🎉 Are you happy?

If you appreciated the support, know that it is free and is carried out on personal time ;)

A support, even a little bit makes a difference for me and continues to bring you answers!

github opencollective

@Romakita
Copy link
Collaborator

Romakita commented Nov 2, 2023

🎉 This issue has been resolved in version 7.43.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants