soul icon indicating copy to clipboard operation
soul copied to clipboard

Authentication Tasks

Open AbegaM opened this issue 1 year ago • 25 comments

Feb 14, 2024

Tasks

Features that will be executed when soul boots up

  • [x] Insert a default role in the _roles table after a role table is created
  • [x] Insert default permissions for all tables after the _roles_permissions table is created

AbegaM avatar Feb 14 '24 12:02 AbegaM

Feb 15, 2024

Tasks

  • [x] Feature to update a normal user to super user

    1. Modify the cli.js file and add an `updateuser` command 
    2. Add a function named `updateUser`
    3. Add a feature to fetch the user from the Db by using the `userId` and then update the `is_superuser` flag
    4. Add a feature to check the password strength and then hash the password and save it in the DB
    

AbegaM avatar Feb 15 '24 08:02 AbegaM

Feb 19, 2024

Tasks

  • [x] Feature to register users

    1. [x] Add a middleware function named processCustomRequest

      • [x] Check if the request is sent to POST /api/tables/_users/rows
      • [x] Call a function named modifyUserPayload
        • [x] Check if the username is taken ==> If true throw an error
        • [x] Check if the password is strong ==> If not throw an error
        • [x] Generate salt and hash the password
        • [x] Generate a new user payload data
        • [x] Create the user in the DB
        • [x] Find the default role from the _roles table
        • [x] Create a role for the user in the _users_role table
        • [x] Return a success message for the client
    • [x] Add a middleware function named processCustomResponse

      • [x] Check if the request is sent to /api/tables/_users/rows
      • [x] Call a function named removeFieldsFromUserPaylod
        • [x] Delete the password and the salt fields
        • [x] Execute the next() middleware

AbegaM avatar Feb 19 '24 12:02 AbegaM

Return the user data by removing the salt and the password

For create only a success report is returned: https://github.com/thevahidal/soul/blob/main/docs/api/rows-examples.md#2-insert-a-new-row

IanMayo avatar Feb 19 '24 12:02 IanMayo

Return the user data by removing the salt and the password

For create only a success report is returned: https://github.com/thevahidal/soul/blob/main/docs/api/rows-examples.md#2-insert-a-new-row

ok, i will update the task description 👍

AbegaM avatar Feb 19 '24 12:02 AbegaM

Feb 20, 2024

Tasks

  • [x] Obtain Access Token Feature

    • [x] Add a router

      /api/auth/token/obtain
      
    • [x] Build a controller function for the feature

      • [x] Extract the username and the password from the body

      • [x] Find the user by using the username

      • [x] Compare the users password with the stored password

      • [x] Get the users role from the DB

      • [x] Generate token

        Create a function called generateToken
        
      • [x] Send the token in the cookie

AbegaM avatar Feb 20 '24 12:02 AbegaM

Feb 22, 2024

Tasks

  • [x] Add a router for the feature

    /api/auth/token/refresh
    
  • [x] Build a controller function for the feature

    • [x] Decode the token with your decodeToken function
    • [x] Check if the subject is accessToken if not throw 401 error
    • [x] Check if the user exists in the database and if not throw 401 error
    • [x] Generate a new access token and refresh token for the user
    • [x] Return the access token in the cookie

Fix PRs based on provided commetns

  • [ ] Move all of the default table names and role values to a constants folder
  • [ ] Add two if statements to check the roleTable and rolesPermssionTable
  • [ ]

AbegaM avatar Feb 22 '24 08:02 AbegaM

Feb 26, 2024

Tasks

  • [x] Add a new middleware function named isAuthorized

    • [x] Add the isAuthorized middleware function in all of the routers

    • [x] Middleware function flow

      • [x] Check if authMode is true or false

        If authMode is true proceed with the authorization but if it is false then call the controller function
        
      • [x] Verify the token

      • [x] Extract the token payload

      • [x] Check if the user is a super user

        If the user is a super user then call the controller function
        If the user is not a super user check the users role 
        
      • [x] Get the users role and permission on the resource

        If the user has permission on the resource then call the controller function
        If not then throw an error
        
  • [x] Fix the unit tests that are failing

      All of the tests are failing due to the authorization middleware function and each test suite needs to send a token in the API call
    

AbegaM avatar Feb 26 '24 08:02 AbegaM

Feb 27, 2024

Tasks

  • [ ] Modify the existing code to handle users with multiple roles

AbegaM avatar Feb 27 '24 11:02 AbegaM

Feb 28, 2024

Tasks

  • [x] Create a function named createSuperuser that will create an initial superuser if there is no superuser in the DB

    • [x] Check if there is a superuser in the DB, if yes then skip creating a superuser
    • [x] Pull the username and password of the superuser from the .env , if these values are not passed throw an error
    • [x] Check if the username is taken, if yes then throw an error
    • [x] Check if the password is strong, if not then throw an error
    • [x] Create the superuser in the DB
  • [x] Modify the existing code to handle users with multiple roles

    • [x] Modify the createDefaultTable function

      Modify the table schema and allow multiple role for a user
      
    • [x] Modify the obtainAccessToken function

      Send multiple roles in the token payload
      
    • [x] Modify the isAuthorized middleware function

      Modify the function to check multiple permissions on a specific resource
      

Fix Comments on this PR, #148

  • [ ] Fix typo error
  • [ ] Separate the if conditions for the creation of _roles_permissions and _roles
  • [ ] Check what happens if the default roles are already created

AbegaM avatar Feb 28 '24 09:02 AbegaM

Testing the Authentication Feature

1. Running soul In Auth mode

1.1 Description

  • This feature enables you to run Soul in authentication mode, where all default endpoints are locked.

1.2 Steps to run Soul in development mode

  1. Add these config variables in your .env file

    AUTH=true
    
    ACCESS_TOKEN_SECRET=ABCD23DCAA
    ACCESS_TOKEN_EXPIRATION_TIME=10H
    
    REFRESH_TOKEN_SECRET=ACDED22CCC
    REFRESH_TOKEN_EXPIRATION_TIME=10H
    
    INITIAL_USER_USERNAME=<user_name> 
    INITIAL_USER_PASSWORD=<password>
    
  2. Run this command in your terminal to run Soul in Auth mode

    npm run dev
    

1.3 Steps to run Soul in CLI mode

  1. Go the the package.json file and manually update the cli script

    "scripts": {
        "cli": "nodemon src/server.js --database foobar.db --atuh --ats <your_secret> --atet 10H --rts <your_secret> --rtet 3D --iuu <user_name> --iup <password>",
      },
    
  2. Run the cli script in your terminal

    npm run cli
    

1.4 What to expect from the above steps

  • When running Soul in development mode and passing the JWT secret values, username, and password, Soul will enable authentication on the APIs and perform the following actions.

    1. Soul creates 4 new tables in the DB: _users, _users_roles, _roles_permissions, and _roles

      NOTE: You can test the existence of the tables by using a GUI tool such as `DB Browser For SQLite` 
      
    2. Soul creates a role with name = default in the _roles table and it will also create list of permissions for the default role in the _roles_permissions table

    3. Soul creates an initial user by taking the username and the password from the .env file

2. Obtain access token feature

2.1 Description

  • To initiate the login process, we begin by running Soul in AUTH mode, which generates an initial user. Next, we proceed to log in using the provided user credentials.

2.2 Steps to Obtain Access Token

  1. Go to your HTTP client such as Postman and send a request to this endpoint

    POST localhost:8000/api/auth/token/obtain
    
    BODY {
        "fields": {
          "username": "<user_name>",
          "password": "<password>"
         }
      }
    
  2. Check the API response, you should get the user ID and a success message

    {
        "message": "Success",
        "data": {
            "userId": 2
        }
    }
    

3. Elevate users to superuser feature

3.1 Description

  • At this stage, Soul has successfully created a default user during the initial step. However, this user does not possess the necessary permissions to perform CRUD operations on certain resources. Therefore, the next step involves elevating this user to a superuser status.

3.2 Steps to elevate a default user to a superuser

  1. Go to the package.json file and update the CLI script

    "scripts": {
        "cli": "nodemon src/server.js --database foobar.db updateuser --id=1 --is_superuser=true"
      },
    
  2. Check if the users status is changed, by using DB Browser For SQLite

    You can check the _users table to check if the is_superuser column has been changed to "true" for the user
    

4. Change password feature

4.1 Description

  • After the user is created, you can change the password either through the API or from the terminal.

4.2 Steps to change password from the API

  1. Open your HTTP client and send a request to this API

    PUT localhost:8000/api/auth/1/change-password
    
    BODY {
            "fields": {
               "currentPassword": "hello@32C#$",
               "newPassword": "ab12#C$AAv"
             }
       }
    
  2. Check the response of the API, you should get this kind of response

    {
        "message": "Password updated successfully",
        "data": {
            "id": 1,
            "username": "superuser"
        }
    }
    
  3. Go to step 2 and try to send a request to the obtain access token endpoint with the new changed password

4.3 Steps to change password from the CLI

  1. Go to the package.json file and update the CLI script

    "scripts": {
        "cli": "nodemon src/server.js --database foobar.db updateuser --id=1 --password=<new_password>
      },
    
  2. Go to step 2 and try to send a request to the obtain access token endpoint with the new changed password

5. Refresh Access token feature

5.1 Description

  • This feature enables frontend clients to refresh their access token using the refresh token when their access token has expired.

5.2 Steps to refresh your access token

  1. Open your HTTP client and send a request to this API

    GET localhost:8000/api/auth/token/refresh
    

    Note: You don't need to manually send the accessToken or the refreshToken as they are already stored in the cookie. Your HTTP client will automatically include them in the requests.

  2. To check for new refresh and access token values in the Postman "cookie" tab, navigate to the "cookie" section in your Postman application and verify if there are updated refresh and access token values present.

6. Create roles and permissions

6.1 Description

  • In this step, you will create a new role and assign a list of permissions to it. After creating this role, you should assign it to your user, allowing the user to have multiple roles.

6.2 Steps to create a new role and permissions

  1. Open your HTTP Client and send a request to this API to create a new role named customerService

    POST localhost:8000/api/tables/_roles_permissions/rows
    
    BODY {
      "fields": {
            "name": "customerService"
        }
    }
    
  2. Chek the response, you should get this kind of response

    {
        "message": "Row inserted",
        "data": {
            "changes": 1,
            "lastInsertRowid": 2
        }
    }
    
  3. Send a new request to the API below to create list of permissions for the new role

    POST localhost:8000/api/tables/_roles_permissions/rows
    
    BODY {
       "fields": {
            "role_id": "<role_id_of_customerService_role>",
            "table_name": "_users",
            "create": "false",
            "read": "false",
            "update": "false",
            "delete": "false"
        }
    }
    

    Note: In the example provided above, a permission has been created for the customerService role regarding the _users table. It has been decided that this role will not have any permissions on this particular table.

7. Authorization feature

7.1 Description

  • This feature ensures that only users with the appropriate permissions can access specific endpoints. It is important to note that the superuser has unrestricted access to all APIs without requiring authorization. However, users with other roles must possess specific permissions to access particular APIs.

7.2 Steps to test the authorization feature

  1. Send a request to any endpoint with the user you created

    GET localhost:8000/api/tables/_users/rows
    
  2. If the currently logged-in user does not possess the READ permission for the _users table, this step will result in an error indicating the lack of authorization.

    {
        "message": "Invalid Access Token"
    }
    

AbegaM avatar Feb 29 '24 13:02 AbegaM

Mar 01, 2024

Tasks

  • [x] Fix the comments on PR, [#148](https://github.com/thevahidal/soul/pull/148)

    • [x] Fix typo error
    • [x] Separate the if conditions for the creation of _roles_permissions and _roles
    • [x] Move the default role to the constants folder
    • [x] Check what happens if the default roles are already created
  • [x] Fix the comments on PR [150](https://github.com/thevahidal/soul/pull/150)

    • [x] Modify the description in the README file
    • [x] Change the updateuser CLI command to updatesuperuser
    • [x] Fix the merge conflicts
  • [x] Fix the comments on PR 152

    • [x] Add a validation on the processRequest middleware to avoid accessing the default endpoints while AUTH is set to false
    • [x] Fix the merge conflicts

AbegaM avatar Mar 01 '24 11:03 AbegaM

Mar 04, 2024

Tasks

  • [x] Fix comments on PR [153](https://github.com/thevahidal/soul/pull/153)
    • [x] Change the enables word to instructs
    • [x] Specify the values for secret and expiration time values
    • [x] Change the userRole variable to userRoles
    • [x] Add a secret and expiration time for both access tokens and refresh tokens and modify the documentation
    • [x] Fix merge conflict in the branch
  • [x] Fix comments on PR [154](https://github.com/thevahidal/soul/pull/154)
    • [x] Add a userId in the error message
    • [x] Use separate secret and exp time for the access token and refresh token
  • [ ] Fix comments on PR [156](https://github.com/thevahidal/soul/pull/156)
  • [ ] Fix comments on PR [157](https://github.com/thevahidal/soul/pull/157)
  • [ ] Fix comments given by @mu
    • [ ] Delete API is throwing FK not found error
    • [ ] createInitialUser function is creating a superuser instead of a normal user
    • [ ] Users are able to change the superuser status via the REST API

AbegaM avatar Mar 04 '24 10:03 AbegaM

Mar 05, 2024

Tasks

  • [x] Endpoint to update users
  • [x] Check the validations on the _users endpoint
    • [x] Check all the GET , POST , PUT and DELETE endpoints and remove some fields like is_superuser, salt , hashed_password and password fields
  • [x] Add a validation on the /tables endpoint to avoid creating reserved table names

AbegaM avatar Mar 05 '24 10:03 AbegaM

Mar 07, 2024

Tasks

  • [ ] Modify the swagger setup for the new endpoints

AbegaM avatar Mar 07 '24 13:03 AbegaM

Amazing job with the authentication features! Definitively improves a lot the usage of Soul

/tip 10 @AbegaM

RubenRuCh avatar Mar 19 '24 22:03 RubenRuCh

Hi @AbegaM, @RubenRuCh wants to tip you $10.00 for your amazing work 🥳 @AbegaM go to your settings and make sure your Stripe account is configured, otherwise you won't be able to receive payments. @RubenRuCh you can pay the tip in your dashboard

opirebot[bot] avatar Mar 19 '24 22:03 opirebot[bot]

Ups... @RubenRuCh tried to complete the payment of $10.00 as a tip to @AbegaM, but @AbegaM doesn't have their payment account configured yet 😱

Please @AbegaM, go to your settings and complete your onboarding! After that, let @RubenRuCh know so they can start the payment process again.

opirebot[bot] avatar Mar 19 '24 22:03 opirebot[bot]

Amazing job with the authentication features! Definitively improves a lot the usage of Soul

/tip 10 @AbegaM

Thank you, @RubenRuCh. I appreciate your feedback.

AbegaM avatar Mar 21 '24 15:03 AbegaM

Mar 21, 2024

Tasks

  • [ ] Change Boolean string values to 1/0

  • [ ] Change auth strategy

    • Refactor the hasAccess middleware function, Obtain access token API, and the refresh access token APIs

AbegaM avatar Mar 21 '24 15:03 AbegaM

Amazing job with the authentication features! Definitively improves a lot the usage of Soul /tip 10 @AbegaM

Thank you, @RubenRuCh. I appreciate your feedback.

No problem! Btw were you able to setup your payment account in Opire, so I can finish the payment of the tip?

RubenRuCh avatar Mar 21 '24 15:03 RubenRuCh

Amazing job with the authentication features! Definitively improves a lot the usage of Soul /tip 10 @AbegaM

Thank you, @RubenRuCh. I appreciate your feedback.

No problem! Btw were you able to setup your payment account in Opire, so I can finish the payment of the tip?

Thank you, @RubenRuCh, but unfortunately, my Stripe account is not working due to some financial regulations in my country. So, you can make the donation to @IanMayo.

AbegaM avatar Mar 21 '24 15:03 AbegaM

Amazing job with the authentication features! Definitively improves a lot the usage of Soul /tip 10 @AbegaM

Thank you, @RubenRuCh. I appreciate your feedback.

No problem! Btw were you able to setup your payment account in Opire, so I can finish the payment of the tip?

Thank you, @RubenRuCh, but unfortunately, my Stripe account is not working due to some financial regulations in my country. So, you can make the donation to @IanMayo.

Sorry to hear that! I'm willing to make the donation to @IanMayo but unfortunately the Opire bot has being uninstalled from the repo :cry: Could you reinstall it? @thevahidal

RubenRuCh avatar Mar 21 '24 15:03 RubenRuCh

Hey @RubenRuCh,

Sorry, but I had to uninstall Opire. Soul's main contributors weren't too thrilled with its comments, so I had to let it go. I actually really liked the idea behind Opire, so I installed it in my other projects to keep supporting it. Hopefully, we can still grow together!

thevahidal avatar Mar 22 '24 10:03 thevahidal

Mar 25, 2024

Tasks

  • [ ] Add a logout API to remove access and refresh tokens
    • [ ] Add a swagger documentation setup for the new API

AbegaM avatar Mar 25 '24 08:03 AbegaM

Apr 01, 2024

Tasks

  • [ ] Add a feature to handle revoked refresh tokens

    • [ ] Store the refresh token in the DB when the user logs out
    • [ ] Modify the /api/auth/token/refresh endpoint to check revoked tokens before refreshing a token provided by the client

AbegaM avatar Apr 01 '24 08:04 AbegaM