‣ Modules
Node & NPM
Some of our packages are a bit finicky so we need specific (ish) versions of npm and node to install and run the api.
For npm:
If you have any version of npm installed you can use npm to install any version of itself:
sudo npm install -g npm@6.14.15
For node:
On linux, first check if you have node at all
whereis node
Then check the version:
node -v
Anything above 12.11.x should work. if not continue bellow.
sudo apt-get auto-remove nodejs
sudo apt-get install nodejs
node -v
You should now be on v12.22.6.
API
- In this directory run
npm install - To start in development mode with apollo playground
npm run start-pg, to develop against the react frontendnpm run start-ui - Do your work in
./src
If it gets slow or you prefer you can compile the typescript to js on changes and then run nodemon on the compiled (build) js.
- In this directory run
npm install, if you haven't already - Open one terminal and run
npm run watch - Open another terminal and run
npm run start-dev-bd - Do your work in
./src
DB LOCAL!
Note: we now host the db remotely so you can skip this step unless you want to fiddle locally
Install mongo, docs
-
sudo systemctl start mongod -
Check it booted
sudo systemctl status mongod -
Connect
mongosh -
Set the db (for dev)
use firstround-dev -
Change the databaseUIR var in
src/init/connectDB.tsto your local instance.
.
├── firebase-conf.json
├── firebase.json
├── package.json
├── package-lock.json
├── README.md
├── src
│ ├── entities
│ ├── index.ts
│ ├── init
│ ├── middleware
│ ├── resolvers
│ └── utils
├── storage.rules
└── tsconfig.json
tsconfig.json- This defines what the linter should complain about and to what detail
package.jsonholds the configs for dependencies and running the projectbuildholds the compiledjscode generated by the bundler, you don't need to worry about this directorysrcentitiesis where schemas are defined using typegoose and type-gql decoratorsindex.tsis the heart of the server it starts the DMBS connection and handles top-level server configurationsinitholds scripts to help with startup configurationsmiddlewaredefines middleware for use in@UseMiddleware()decoratorsresolversdefines the primary logic for handling gql queries, most of the work happens hereutilsassortment of helper functions and ts interfaces, importantlyAppContextand jtw strategy is implemented here
To get CORS to behave and accept cookies you must change the CORs options in index.ts depending on the use case. At some stage i'll make this a runtime flag.
- If running the server for the frontend set the origin to process the
CLIENT_ORIGINenvironment variable - If testing the server in apollo studio/playground set the origin to process the
PLAYGROUND_OGenvironment variable
Note: if working in the playground you need to make sure that include credentials is turned on in the settings ⚙️ in the endpoint url.
Firefox: in firefox the cookie will not appear in the cookies list in storage when working in the apollo playground because Firefox has decided that any cookie with the domain localhost gets yeeted from the list. However, the cookie is actually present and will work correctly with the auth middleware.
Sensitive API resolvers are protected from unauthenticated users based on whether:
- The client holds a valid (signed) JWT
- The clients valid JWT holds a specific user type
For the first case the Authorised middleware is used in the following fashion.
@UseMiddleware(Authorised)
@Query(() => String)
resolver(
@Ctx() { jwtPayload }: any
) {
// Only users with a valid token can cause this
// resolver to fire
// access to user info through `jwtPayload`
}For the secondary case the above Authorised middleware must be called first to populate the context
with the users JWT token. A secondary middleware can then be supplied to restrict access to the resolver
based on user type/role. Valid secondary middleware's' are:
isBusinessAdminRoute
Sample usage is as follows.
Note: middleware is called in the order it is defined.
@UseMiddleware(Authorised, isBusiness)
@Mutation(() => String)
adminHealth(
@Ctx() { jwtPayload }: any
) {
// only authenticated business users
// can trigger this resolver
}- Install
@types/as devDependencies,npm i <package> --save-dev - Install everything else as normal