Week 1 & 2- CircuitVerse@GSOC'23
CircuitVerse X GSoC - Coding period report - Arnab Das
Hello, everyone this is my first blog for GSoC 23 coding period.
Community Bonding Period
The community bonding period starts from the day when we receive the acceptance email from Google. During the community bonding period, all the members and contributors had meets to introduce each other and their projects. next, we had individual meets with our mentors to know each other better and also discuss about the project. we had discussions about any changes in the timeline and also about any better ways to implement the project.
my tasks during the community bonding period were:
gaining a deeper knowledge of the codebase
some research about other possible alternatives for some parts of project implementation.
After the community bonding period, the official coding period begins on 29th May 2023
Goal of first two weeks:
Integration of Vue simulator with main repository
Creation of new API endpoints for Vue simulator
Week 1: integration of Vue simulator repo with the main repository
due to timeline changes during the community bonding period, I decided to start working on week 1 and week 2 tasks together. but I am writing both separately for better understanding.
preface: currently the semi-developed vue simulator is kept in a separate repository isolated from the main repository. So, the first task is to connect both of them in order for the Vue simulator to be functional and get deployed.
constraints: there were multiple ways to integrate the vue simulator with the main repository but our target was to keep the vue simulator code independent of the main repository so that it can be developed in isolation in the future.
implementation: keeping the above constraints in mind we decided to use git submodules for the integration.
step 1: git submodule add
https://github.com/CircuitVerse/cv-frontend-vue.git
this adds the vue simulator repository to the main repo as a submodule.
we see two new files
cv-frontend-vue
directory: this is where we would get the code of Vue simulator.gitmodules
this file is like a config file for the git submodules we add to our repo
step 2: git submodule set-branch -b main cv-frontend-vue
with this, we set the submodule to track the branch main for cv-frontend-vue
step 3: git submodule update --init --remote
with this command, we initialize the submodule, set the submodule head to the latest commit on the main branch and clone the cv-frontend-vue repo.
Step 4: Finally we commit and push the changes.
setup for the development and build of the vue simulator with the main repository:
for the build of the simulator, I configured vite to put the static build files of the vue simulator in the public/simulatorvue directory of the main repository.
step 1: update the vite.config.js by adding the following:
base: '/simulatorvue/',
build: {
outDir: '../public/simulatorvue',
assetsDir: 'assets',
chunkSizeWarningLimit: 1600,
},
step 2: define a route for the simulator:
get "/simulatorvue/*path", to: "vuesimulator#simulatorvue" # change to /simulator later
define a new controller at app/controllers/vuesimulator_controller.rb
for handling the route.
now we can access the Vue simulator once build.
for dev environment I decided to have two ways:
using vite build --watch along with the current setup to run the project from a single dev server.
here I updated the esbuild.config.js file to fetch all the updates in the submodule, do
npm install
andnpm run build
when we start the dev server withbin/dev
. I added one environment variableBUILD_VUE
to set either to build or not build the vue simulator when you start the dev server.all changes can be found in pr 3774
maybe modified or changed in the future after the GSoC projects regarding dev and production improvements finish.
using vite proxy to proxy all requests from other paths than the vue simulator's path, to the rails dev server.
although the development of the Vue simulator is possible with the previous implementation, we lose Vite's HMR (hot module replacement). for this, we have the second development approach where we run the main dev server and the Vite dev server together but proxy non-vue simulator requests to the main server.
to implement this we add proxy settings in vite.config.js as
// ... no changes const proxyUrl:string = 'http://localhost:3000'; export default defineConfig({ // ... no changes in between server: { port: 4000, proxy: { '^/(?!(simulatorvue)).*': { target: proxyUrl, changeOrigin: true, headers: { origin: proxyUrl, }, }, }, },
with this, we set up Vite proxy all requests other than the path /simualtorvue/(catch_all*) to the set proxyUrl.
also, we define the port for the Vite server to start at 4000 by default instead of 3000 to not interfere with rails server.
for now, only one path is added to not be proxied but in future, more might be added so always refer to the latest vite config.
other miscellaneous changes:
- update the docker-compose.yml and procfile.dev for the first implementation of dev server.
Week 2: creation of new API endpoints and implementation of JWT in the CircuitVerse site.
preface: as our current target is of making the new simulator independent of the rails counterpart we move toward a fully API-driven application, and for authentication, we move from the current cookie-based system to JWT.
implementation: creating new API endpoints in the api/v1
format:
step 1: Create a new simulator_controller.rb in app/controllers/api/v1 directory.
step 2: add the new api methods in the file as in here
step 3: add the required helper in app/helpers/api/v1/simulator_helper.rb
as in here
step 4: finally adding new routes to routes.rb as in here
the created new api endpoints in api/v1 format:
GET api/v1/simulator/:id/edit
use: check project edit access and load simulator in edit mode accordinglyGET api/v1/simulator/:id/data
use: get project circuit data only if project viewing access is therePATCH api/v1/simulator/update
use: update circuit data for a project with edit accessPOST api/v1/simulator/create
use: create a new project with circuit data and provided namePOST api/v1/simulator/post_issue
use: post user issues and send to slack (as per current implimentation)POST api/v1/simulator/verilogcv
use: send post request to yoyos server and get circuit data from verilog codeany other API endpoints would be added later as per requirement for latest APIs check CircuitVerse api docs
Adding JWT authentication to circuitverse web:
Circuitverse uses devise to handle the authentication so to generate and save JWT it is implemented along with the current devise authentication methods.
for the encoding and stroing jwt during sign_in we update the session_controller.rb as
# POST /resource/sign_in
def create
super do |user|
# Check if 'Remember me' is selected
remember_me = params.dig(:user, :remember_me) == "1"
# Generate JWT token
token = JsonWebToken.encode(
{ user_id: user.id, username: user.name, email: user.email },
remember_me: remember_me
)
cookie_options = {
value: token,
httponly: true,
secure: Rails.env.production?,
same_site: :strict
}
# Set cookie expiration
cookie_options[:expires] = 2.weeks.from_now if remember_me
# Set JWT token as cookie
cookies[:cvt] = cookie_options
end
end
and for sign_up we update registrations_controller.rb as:
# POST /resource
def create
super do |user|
if user.persisted?
# Generate JWT token
token = JsonWebToken.encode({ user_id: user.id, username: user.name, email: user.email }, remember_me: false)
# Set JWT token as cookie
cookies[:cvt] = {
value: token,
httponly: true,
secure: Rails.env.production?,
same_site: :strict
}
end
end
end
for handling sign_out we simply delete the jwt token from cookies as of now which would be improved in future
# DELETE /resource/sign_out
def destroy
super do
# Remove the JWT token cookie
cookies.delete(:cvt)
end
end
the JWT handling in browser is described below:
create and save JWT as cookie on:
sign_up (1-day validity)
sign_in (1-day validity if not remember me / if remember me then 2 weeks validity)
destroy/delete saved cookie:
sign_out ( all cases )
browser close (when not remember me JWT gets deleted as session-based cookie)
for the JWT token configuration & changes, we add the length of the token expiry to be decided based on whether the user checked 'remember me' or not during login. changes can be found here
These are still under review so there might be further changes.