GithubHelp home page GithubHelp logo

2 Questions about scratchy HOT 12 CLOSED

cloudcompute avatar cloudcompute commented on May 18, 2024
2 Questions

from scratchy.

Comments (12)

jasonraimondi avatar jasonraimondi commented on May 18, 2024 2

This would more or less be just rows in our database.

These pivot tables would be taken care of by the ORM, but it is worth noting this is what your database structure ultimately looks like. See here where I am seeding a user and role called "overlord" (ultimately just an admin).

Basically, the user can have many roles. When executing mutations (since this is mostly a graphql API, in rest, the equivalent would be POST), you would have guards in place that protected the routes. Here is how Nest.js handles guards in REST, and here is the relevant GraphQL sections.

Users table:

id username
1 admin-user
2 author-user
3 reader-user
4 moderator-user

Roles table:

id role
1 Admin
2 Author
3 Reader
4 Moderator

A permission table:

id permission
1 article.read
2 article.write
3 users.read
4 users.write
5 comments.read
6 comments.write

The role_permission pivot table

role_id permission_id
1 1
1 2
1 3
1 4
1 5
1 6
2 1
2 2
2 5
2 6
3 1
3 5
4 1
4 5
4 6

user_roles table

user_id role_id
1 1
2 2
3 3
4 4

from scratchy.

cloudcompute avatar cloudcompute commented on May 18, 2024 1

Wonderful!

I have started configuring the code. I may come up with few questions. Hope you'd reply.

Thanks.

from scratchy.

cloudcompute avatar cloudcompute commented on May 18, 2024 1

The 'wip' branch was 1 commit ahead than the 'master' branch. Therefore I cloned the 'wip' branch. Over there, it is 1 (and not 10): Here is the link:

I compared both the branches, Hope I am not losing any more changes while using the 'wip'.
https://github.com/jasonraimondi/scratchy/compare/wip

With these server rendered pages, the CSRF token was necessary.

I will use the SPA (create-react-app) instead of Next. Looks like, in the SPAs, CSRF protection is not necessary. I will read more about it and try to implement it of my own. Taking care of Security is among the most difficult.

Thank you once again for putting me on the track.

from scratchy.

cloudcompute avatar cloudcompute commented on May 18, 2024

Probably we need to set the mailerURL env variable.

from scratchy.

jasonraimondi avatar jasonraimondi commented on May 18, 2024

Hey, so this project is more or less my playground slash boilerplate project for if I wanted to start a production GraphQL API and Next.js client. I've used it to try out different ORM's, starting as a TypeORM project, and ultimately switching to PrismaJS.

I would definitely consider this project almost production ready, it was built with the intention that you'd be able to have different release versions (dev, staging, production) and has background job support using bulljs and email support using Nunjucks and MJML.

You are correct, if you wanted to change to use Sendgrid's SMTP server, you would use the environment variable MAILER_URL as exampled here.

The permission functionality is as implemented as it can be, without having any set rules for who can do what (what user has what role, with what permission). You would expand upon the configured permissions by creating custom roles and permissions, created for your application.

Feel free to fork this project and make it your own.

from scratchy.

cloudcompute avatar cloudcompute commented on May 18, 2024

Thanks a lot for the reply. I am glad to know that the code can be used in production. Kindly give a real-world example that help explain expand upon the configured permissions (which source code files) by creating custom roles and permissions.

For example 3 roles: Admin, Author, Reader, Moderator

Permissions:
Author can write an article but cannot see the list of all users.
List of users are made available to admin only.
Readers can read/view the articles and create comments on them.
Moderate can edit the comments but cannot author the articles.

Could you pl. write the sample code for it?

Thanks

from scratchy.

cloudcompute avatar cloudcompute commented on May 18, 2024

I had a look at the code and got to see the redis-based bull queue.

from scratchy.

cloudcompute avatar cloudcompute commented on May 18, 2024

@jasonraimondi

Thank you for the detailed explanation. Yesterday, I had a look at the seed-data. I almost got it but the word "overlord" made me wonder what it is referring to. Now I got to know you meant "admin"

As I have seen developers using jwt-decode at the client side. They fetch the current date/time from the client's machine. But the token was created using the server-side's date/time. What if the date/time of the client and server machine have a difference of let's say several hours or may be days. Am I wrong somewhere in perceiving this concept?

You are using RxJs at the client side. Is this library being used with an assumption that we should manage the entire state of the client app using RxJS.. instead of using standard libraries like Redux, MobX?

With Regards

from scratchy.

jasonraimondi avatar jasonraimondi commented on May 18, 2024

The timestamps are stored as epoch timestamps which are independent of timezone. Epoch timestamps (new Date().getTIme() / 1000 or Date.now()) when decoded by the client browsers will automatically convert to the browser time.

const date = new Date();
const timestamp = date.getTime();
const epochTimestamp = date.getTime() / 1000; // divide by 1000 to get timestamp in seconds (typical epoch)

// then on the browser
const date = new Date(timestampMilliSeconds);

Rxjs is optional, you are free to use it if you'd like, otherwise it will be tree shaken out.

from scratchy.

jasonraimondi avatar jasonraimondi commented on May 18, 2024

Sounds good, will do what I can

from scratchy.

cloudcompute avatar cloudcompute commented on May 18, 2024

This quality of this source code is excellent.

Reference:
https://stackoverflow.com/questions/42581421/where-does-javascript-get-a-new-date-from/42581497#comment72295334_42581488

If we look at the answers stated in the URL above, it tells us that the current date and time are retrieved from the client's local environment/machine. Actually, when I pointed out a concern regarding the difference between server and client date/time, I wanted to indicate that if someone gets hold of an expired access token, he can adjust the local clock and fools the system and make it believe that the token has not yet expired.

const isAuthenticated = (() => {
if (!state.accessToken || !decodedToken) return false;
const expiresAt = new Date(decodedToken.exp * 1000);
return new Date() < expiresAt; //here the browser is returning the local date/time
})();

..

In bcryptjs.hash() the value of salt rounds is only "1". Better if we keep this value somewhere around 8 or 10, probably more security. Do you agree to this?

..

CSRF functionality (fastify.register) is there at the API end. Then sending the csrfToken in a hidden field:

The csrfToken's value is not getting set/stored anywhere at the server end. Is this functionality fully implemented? Do we need to send this hidden field in all the React forms? Right now, you are using this hidden in the server-side templating system (Nunjucks).

..

I need to add support for error handling that can handle db and graphql errors in dev and prod modes. The main difference is that in dev mode, we should be able to see the Stack trace in the browser. Whereas in production mode, some error code is displayed asking the end user to notify this error code to the system admin. Something like that.. any hints how to implement it in nestjs.

Sincere regards

from scratchy.

jasonraimondi avatar jasonraimondi commented on May 18, 2024

if someone gets hold of an expired access token, he can adjust the local clock and fools the system

This is not a security concern for the API because the access tokens are signed JWT with a secret password set in the JwtStrategy. If anyone was to manipulate this data and attempt to extend the duration, the token would fail verification, and the API would return an Unauthorized 401 (if the endpoint/query/mutation requires auth).

This is not really a security concern for the client either, because as soon as the client attempts to do anything with that token (like retrieving secret data that only the token holder should see) the API will fail, and the frontend will receive 401s and basically enter error states.

In bcryptjs.hash() the value of salt rounds is only "1"

Where do you see this value set as 1? Our hash function is set to 10 salt rounds by default as seen here in utils/passwords.ts

CSRF & Right now, you are using this hidden in the server-side templating system (Nunjucks).

So this project has been through a few phases, and one of those phases was implementing my oauth2-server package. When that was the case, I was using nunjucks templating for the oauth2 login page as well as the scope acceptance pages ("Do you allow this project to edit your projects, read your projects etc"). With these server rendered pages, the CSRF token was necessary.

The CSRF token should also be set for the register and login endpoints (basically... wherever a token is not required to POST). Meaning, if you have a form open to the world (login, register, password reset), it should be protected by CSRF. This is not the case for this project currently. I have not implemented anything to send the CSRF token to the Next.js client yet.

It is worth noting that Nunjucks is still used for email templating for the server (along with MJML). You can see the email templates here

I need to add support for error handling that can handle db and graphql errors in dev and prod modes

The graphql configuration along with formatError configuration is located here in the config/graphql.ts. You could just add some magic in that function to check the ENV.isProduction value.

from scratchy.

Related Issues (1)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.