faker-js / faker

Generate massive amounts of fake data in the browser and node.js
https://fakerjs.dev
Other
12.56k stars 903 forks source link

add `jwt` to `internet` module #1282

Open xDivisionByZerox opened 2 years ago

xDivisionByZerox commented 2 years ago

Clear and concise description of the problem

As a developer, I use faker to "seed" my documentation examples. I was currently writing a section about the usage of the JWT token in my system. For visualization purposes, I wanted to provide an example JWT so developers can see what to expect. Sadly faker doesn't provide such a feature (at least not in the internet module where I would expect it).

Suggested solution

Add a basic jwt function to the internet module that returns a string that is a JWT. So it should be "decryptable" but has a random signature.

I don't think it's necessary to input a payload object since that would get too close to a real implementation (?).

Alternative

Currently, I use a hardcoded JWT (with incorrect signature and expired) for my documentation.

Additional context

No response


[!NOTE]
This issue has been marked with "good first issue". If you'd like to get started contributing to this project, this is the issue for you! The issue can be solved by following the acceptance criteria layed out in the team decision comment

ST-DDT commented 2 years ago

What would be the benefit of a generated invalid token over a static expired one?

xDivisionByZerox commented 2 years ago

Just so I understand you correctly. You suggest doing the following:

@MyDocumentationDecorator({
  example: myJwtLib.generate(realPayload, secret, { expiresIn: dateInThePast }),
})

This is not possible for me because the part where I write the documentation doesn't depend on the implementation of the JWT generation (or any business logic tbh). So I'm not able to access myJwtLib because it's abstracted in a way that only the service that is responsible for JWT generation knows the exact implementation. And to go a step further I'm not able to use that service in the documentation due to it (the documentation) being a decorator based and the services have to be injected by the framework for dependency resolution.

One more thing: My current solution works perfectly fine (with a static/hardcoded JWT string). I just like to have example values change every time you reload to documentation, but its not required.

BrianMcBrayer commented 1 year ago

I'd be interested in Faker having this too.

xDivisionByZerox commented 1 year ago

Please upvote the issue if you are interested in having this in Faker. That way we can track user interest.

BrianMcBrayer commented 1 year ago

Please upvote the issue if you are interested in having this in Faker. That way we can track user interest.

Silly question but how do I upvote?

xDivisionByZerox commented 1 year ago

With "upvote" we mean the +1 (👍) reaction in issues and PRs.

But I saw that you already found it 👍


More information on reactions can be found on "Add Reactions to Pull Requests, Issues, and Comments"

github-actions[bot] commented 1 year ago

Thank you for your feature proposal.

We marked it as "waiting for user interest" for now to gather some feedback from our community:

Shinigami92 commented 5 months ago

An example call could look like:

const jwt: string = faker.internet.jwt({
  algorithm: faker.internet.jwtAlgorithm(),
  refDate: faker.date.past(),
});

But what should be returned? Should header contain { alg, typ }? Should payload contain { sub, name, exp, iat }?

ST-DDT commented 5 months ago

Or more specifically:

What are your requirements/expectations?

xDivisionByZerox commented 5 months ago

Proposal for minimalistic API implementation

The following text uses "Requirement Levels" based on RFC 2119

What are your requirements/expectations?

As stated in my original feature request:

Add a basic jwt function to the internet module that returns a string that is a JWT. So it should be "decryptable" but has a random signature.

I don't think it's necessary to input a payload object since that would get too close to a real implementation (?).

We can asset multiple things here:

Additionally, I suggest that the initial method SHOULD be as minimalistic as possible.

The following sections are suggestions that should summarize the higher level implementation details for faker.internet.jwt.

Headers

Payload

Signature

Example implementation

jwt(): string {
  const header = {
    alg: randomJwtHeaderAlgorythm(), // abstracted here
    typ: 'JWT',
  };
  const payload = {
    iat: this.faker.date.anytime().valueOf(),
    exp: this.faker.date.anytime().valueOf(),
  };

  const encodedHeader = Buffer.from(JSON.stringify(header)).toString('base64url');
  const encodedPayload = Buffer.from(JSON.stringify(payload)).toString('base64url');
  const signature = faker.random.alphaNumeric(64);

  return `${encodedHeader}.${encodedPayload}.${signature}`;
};

Feel free to give feedback on the proposal.

ST-DDT commented 5 months ago
  • The header object MUST include the properties "typ" and "alg"

These headers are also optional according to the spec. I didn't find any specifics regarding alg at all. Maybe lets consider alg as required.

  • The payload object MUST include the properties "exp" and "iat"

These claim names are also optional according to the spec.

Additionally, I suggest that the initial method SHOULD be as minimalistic as possible.

If it should be as minimalisistic as possible, it should omit all optional fields. Which basically results in {"alg": "HS256"}.{}.ZRrHA1JJJW8opsbCGfG_HACGpVUMN_a9IV7pAx_Zmeo

eyJhbGciOiJIUzI1NiJ9.e30.ZRrHA1JJJW8opsbCGfG_HACGpVUMN_a9IV7pAx_Zmeo

What is your intention doing with such a value? Since it doesn't contain any values (and is invalid) what can you do with it? If you cannot do anything with it, why not hardcode the first two parts? Or just use 3 random base64 strings?

It would be a different matter if you could provide the/additional header and payload entries. Then you could actually create JWT tokens according to your needs (except their signature). But then again why would your application ever process a JWT token, that isn't valid?

Providing a valid signature isn't possible without specific libraries, not available in all environments (e.g. node:crypto)

xDivisionByZerox commented 5 months ago
  • The header object MUST include the properties "typ" and "alg"

These headers are also optional according to the spec. I didn't find any specifics regarding alg at all. Maybe lets consider alg as required.

  • The payload object MUST include the properties "exp" and "iat"

These claim names are also optional according to the spec

My comment was not a summary of RFC7519 but a "Proposal for minimalistic API implementation" (as stated in the first heading) - a suggested specification for the implementation. If this intent was not clear enough, I apologize for that.

Additionally, I suggest that the initial method SHOULD be as minimalistic as possible.

If it should be as minimalisistic as possible, it should omit all optional fields. Which basically results in {"alg": "HS256"}.{}.ZRrHA1JJJW8opsbCGfG_HACGpVUMN_a9IV7pAx_Zmeo

eyJhbGciOiJIUzI1NiJ9.e30.ZRrHA1JJJW8opsbCGfG_HACGpVUMN_a9IV7pAx_Zmeo

While this would be true when strictly following the RFC, I'd argue that real-world use cases nearly always include the "typ" property in the header as well as the properties "exp" and "iat" in the payload. That's the reason why I suggested including them.

What is your intention doing with such a value? Since it doesn't contain any values (and is invalid) what can you do with it? If you cannot do anything with it, why not hardcode the first two parts? Or just use 3 random base64 strings?

It would be a different matter if you could provide the/additional header and payload entries. Then you could actually create JWT tokens according to your needs (except their signature). But then again why would your application ever process a JWT token, that isn't valid?

As stated in my original comment as well: The workaround with a static value works for me. My use case was to generate dynamic example values in the documentation I was working on back then. Non-tech people (testers) had to use an API interface (think swagger) and had to extract the JWT they got from a response. The documentation showed them the value of the format that they could expect. My use case might not be the most sophisticated but seeing that this issue collected over 20 upvotes during the last year I'd say that the necessity from the community is given.

Providing a valid signature isn't possible without specific libraries, not available in all environments (e.g. node:crypto)

Agreed, this is why I made the statements in the suggestion, covering the necessity to not include valid signatures.

ST-DDT commented 5 months ago

Team Decision

eLoyyyyy commented 4 months ago

I'll get this feature. This is going to be my first, so please be kind.

ST-DDT commented 4 months ago

Welcome to the project. I assigned the issue to you.