Step 2 - Create Backend Using Expressjs
Tags: dohackathon
Published: 2021-01-03 03:44:08

Clone this repo in order for you to follow this tutorial :

{% github spiritbro1/opensource-marketplace-backend %}

Now create a simple expressjs using the express command line like this :

```
mkdir opensource-marketplace-backend
cd opensource-marketplace-backend
npx express-generator
```

We gonna need to connect the database using postgresql so in order to do that we gonna use sequelize for that, run this command to do that :

```
npx sequelize init
```

When you do `npx sequelize init` you will see `config/config.json` file change that to `config/config.js` and add this code :

```javascript
module.exports={
  "development": {
    "username": "panda",
    "password": "panda1234",
    "database": "panda_database",
    "host": "127.0.0.1",
    "dialect": "postgres"
  },
  "test": {
    "username": "root",
    "password": null,
    "database": "database_test",
    "host": "127.0.0.1",
    "dialect": "mysql"
  },
  "production": {
    "username": process.env.DB_USERNAME,
    "password": process.env.DB_PASSWORD,
    "database": process.env.DB_NAME,
    "host": process.env.DB_HOST,
    "port":process.env.DB_PORT,
    "dialect": "postgres",
    "dialectOptions": {
      "ssl": { "require": true, "rejectUnauthorized": false }
    }
  }
}


```

If you see in production object i use `ssl` because in order for us to connect to app platform database later, we need that ssl, also i change all of the hardcoded username,password, etc. to environment variable to add more to the security, so you don't need to worry if your password got stolen coz when we put it to open source, it will be added in safe environment of app platform environment variable, now let's create a table for our apps :

```bash
npx sequelize model:create --name for_sell --attributes repo_id:string,description:string,name:string,openGraphImageUrl:string,url:string,isPrivate:boolean,username:string,sell:string,amount:string

npx sequelize model:create --name owned_repo --attributes repo_id:string,description:string,name:string,openGraphImageUrl:string,url:string,sell:string,amount:integer,owner_username:string,username:string

npx sequelize model:create --name paypal --attributes github_username:string,email:string,amount:integer,disconnect:boolean

npx sequelize model:create --name transaction --attributes random:string,for_sell_id:string,token:string

npx sequelize model:create --name user --attributes username:string, token:text, role:string
```

Now create a `docker-compose.yml` file and add this code:

```yaml
version: '3'
services:
  database:
    image: "postgres" 
    ports:
      - "5432:5432"
    env_file:
      - database.env 
    volumes:
      - database-data:/var/lib/postgresql/data/ 
volumes:
  database-data: 
```

Run using `docker-compose up -d` then run `npx sequelize db:migrate` in order for you to create the table, now go to `bin/www` and change this line :

```javascript
var port = normalizePort(process.env.PORT || '4000');
app.set('port', port);

```

This one will tell our app later to listen at port 4000 in app platform, now go to `routes/index.js` and change the code to this :

```javascript
require("dotenv").config();
const express = require("express");
const router = express.Router();
const model = require("../models/index");
const { github: authorizeGithub } = require("./utils/authorize");
const {
  forSellRepo,
  allRepo,
  ownedRepo,
  profile,
  
} = require("./utils/for_sale");
const { sell_repo, unlist_repo, for_sale_repo, list_repo,repo_detail} = require("./utils/sell_repo");
const {
  authorize_paypal,
  save_paypal,
  get_paypal,
  disconnect_paypal,
} = require("./utils/paypal");
const { buy_paypal, manage_access } = require("./utils/manage_access");

router.get("/authorize_github", async function (req, res, next) {
  const params = {};
  params.code = req.query.code;
  params.token_pass = process.env.token_pass;
  params.frontend_url = process.env.frontend_url;
  params.github_client_id = process.env.github_client_id;
  params.github_client_secret = process.env.github_client_secret;
  const response = await authorizeGithub(params, model);
  return res.redirect(response.headers.location);
});
router.get("/get-for-sale-repo", async function (req, res, next) {
  try {
    const params = {};
    params.token = req.query.token;
    params.token_pass = process.env.token_pass;
    params.frontend_url = process.env.frontend_url;
    params.github_client_id = process.env.github_client_id;
    params.github_client_secret = process.env.github_client_secret;
    const response = await forSellRepo(params, model);
    return res.json(response);
  } catch (e) {
    console.log(e.message);
    return res.status(503).end();
  }
});
router.get("/get-all-repo", async function (req, res, next) {
  try {
    const params = {};
    params.token_pass = process.env.token_pass;
    params.frontend_url = process.env.frontend_url;
    params.github_client_id = process.env.github_client_id;
    params.github_client_secret = process.env.github_client_secret;
    params.before = req.query.before;
    params.after = req.query.after;
    params.token = req.query.token;
    const response = await allRepo(params, model);
    return res.json(response);
  } catch (e) {
    console.log(e.message);
    return res.status(503).end();
  }
});
router.get("/get-owned-repo", async function (req, res, next) {
  try {
    const params = {};
    params.token_pass = process.env.token_pass;
    params.token = req.query.token;
    params.frontend_url = process.env.frontend_url;
     const response = await ownedRepo(params, model);
    return res.json(response);
  } catch (e) {
    console.log(e.message);
    return res.status(503).end();
  }
});
router.get("/get-profile", async function (req, res, next) {
  const params = {};
  params.token_pass = process.env.token_pass;
  params.frontend_url = process.env.frontend_url;
  params.github_client_id = process.env.github_client_id;
  params.github_client_secret = process.env.github_client_secret;
  params.token = req.query.token;
  const response = await profile(params, model);
  return res.json(response);
});
router.post("/sell-repo", async function (req, res, next) {
  const params = {};
  params.name = req.body.name;
  params.amount = req.body.amount;
  params.token = req.query.token;
  params.token_pass = process.env.token_pass;
  params.frontend_url = process.env.frontend_url;
  params.github_client_id = process.env.github_client_id;
  params.github_client_secret = process.env.github_client_secret;
  const response = await sell_repo(params, model);
  return res.json(response);
});
router.post("/unlist-repo", async function (req, res, next) {
  const params = {};
  params.id = req.body.id;
  params.token = req.query.token;
  params.token_pass = process.env.token_pass;
  params.frontend_url = process.env.frontend_url;
  params.github_client_id = process.env.github_client_id;
  params.github_client_secret = process.env.github_client_secret;
  const response = await unlist_repo(params, model);
  return res.json(response);
});
router.get("/for-sale-repo", async function (req, res, next) {
  try {
    const params = {};
    params.token = req.query.token;
    params.token_pass = process.env.token_pass;
    params.frontend_url = process.env.frontend_url;
    params.github_client_id = process.env.github_client_id;
    params.github_client_secret = process.env.github_client_secret;
    const response = await for_sale_repo(params, model);
    return res.json(response);
  } catch (e) {
    console.log(e.message);
    return res.status(503).end();
  }
});
router.get("/paypal-auth", async function (req, res, next) {
  try {
    const params = {};
    params.code = req.query.code;
    params.frontend_url = process.env.frontend_url;
    params.paypal_client_id = process.env.paypal_client_id;
    params.paypal_client_secret = process.env.paypal_client_secret;
    const response = await authorize_paypal(params);
    return res.redirect(response.headers.location);
  } catch (e) {
    console.log(e.message);
    return res.status(503).end();
  }
});
router.post("/save-paypal", async function (req, res, next) {
  try {
    const params = {};
    params.token_pass = process.env.token_pass;
    params.token = req.body.token;
    params.email = req.body.email;
    const response = await save_paypal(params, model);
    return res.json(response);
  } catch (e) {
    console.log(e.message);
    return res.status(503).end();
  }
});
router.get("/get-paypal", async function (req, res, next) {
  try {
    const params = {};
    params.token_pass = process.env.token_pass;
    params.token = req.query.token;
    params.frontend_url = process.env.frontend_url;
    const response = await get_paypal(params, model);
    return res.json(response);
  } catch (e) {
    console.log(e.message);
    return res.status(503).end();
  }
});
router.post("/disconnect-paypal", async function (req, res, next) {
  const params = {};
  params.token_pass = process.env.token_pass;
  params.token = req.query.token;
  params.frontend_url = process.env.frontend_url;
  const response = await disconnect_paypal(params, model);
  return res.json(response);
});
router.post("/buy-paypal", async function (req, res, next) {
  const params = {};
  params.token_pass = process.env.token_pass;
  params.token = req.body.token;
  params.id = req.body.id;
  params.frontend_url = process.env.frontend_url;
  params.return_url = process.env.return_url;
  params.cancel_url = process.env.cancel_url;
  params.paypal_client_id = process.env.paypal_client_id;
  params.paypal_client_secret = process.env.paypal_client_secret;
  const response = await buy_paypal(params, model);
  return res.json(response);
});
router.post("/repo-detail", async function (req, res, next) {
  const params = {};
  params.name=req.body.name
  params.username=req.body.username
  const response = await repo_detail(params, model);
  return res.json(response);
});
router.get(
  "/manage-access/:token/:id/:random",
  async function (req, res, next) {
    const params = {};
    params.token_pass = process.env.token_pass;
    params.token = req.params.token;
    params.id = req.params.id;
    params.random = req.params.random;
    params.frontend_url = process.env.frontend_url;
    params.paypal_client_id = process.env.paypal_client_id;
    params.paypal_client_secret = process.env.paypal_client_secret;
    const response = await manage_access(params, model);
    return res.redirect(response.headers.location);
  }
);
router.post("/list-repo", async function (req, res, next) {
  try{
    const params = {};
  params.item = req.body.item;
  params.token = req.query.token;
  params.token_pass = process.env.token_pass;
  const response = await list_repo(params, model);
  return res.json(response);
  }catch(e){
    console.log(e.message)
    return res.status(503).end()
  }
  
});
router.get("/", async function (req, res, next) {
  return res.send("im healthy");
});
module.exports = router;

```

All of this is our main route in order for our application works, now we need to create all the logic create a folder called `utils` and add new file called `authorize.js` add this code :

```javascript
"use strict";
const axios = require("axios");
const jwt = require("jsonwebtoken");
const formUrlEncoded = (x) =>
  Object.keys(x).reduce((p, c) => p + `&${c}=${encodeURIComponent(x[c])}`, "");
const github = async function (params,model) {
  if (params.code) {
    const { access_token } = await authenticate({ params });
    const { login,email } = await getUsername({ access_token });
    const {token} = await checkUsername({
      username: login,
      model,
      email,
      access_token,
      token_pass: params.token_pass,
    });
    
    if(token){
      return  {
        headers: { location: `${params.frontend_url}/callback/?token=${token}` },
        statusCode: 302
        };
    }else{
      return  {
        headers: { location: params.frontend_url },
        statusCode: 302
        };
    }
    
  } else {
    return {
      headers: { location: `${params.frontend_url}/login` },
      statusCode: 302
      };
  }
};
module.exports.github = github;
async function authenticate({ params }) {
  const { data } = await axios({
    url: "https://github.com/login/oauth/access_token",
    headers: {
      "Content-Type": "application/x-www-form-urlencoded",
      Accept: "application/json",
    },
    data: formUrlEncoded({
      client_id: params.github_client_id,
      client_secret: params.github_client_secret,
      code: params.code,
    }),
    method: "POST",
  });
  return data;
}
async function getUsername({ access_token }) {
  const { data } = await axios({
    url: " https://api.github.com/user",
    headers: {
      Authorization: `token ${access_token}`,
      Accept: "application/vnd.github.v3+json",
    },
    method: "GET",
  });
  return data;
}
async function checkUsername({ username, access_token, model, email,token_pass }) {
  const token = jwt.sign({ access_token }, token_pass);
  
  const [user,created] =await model.user.findOrCreate({where: {username}, defaults: {access_token,
    token,
    email}})
  if (user) {
    const updated=await user.update({access_token,
      token,
      email})
     return updated ? {token}:undefined;
  } else {
    return created ? {token}:undefined;
    
  }
}


```

This is used to authorize to github, add another file called `utils/for_sale.js` for creating logic to put our repo for sell :

```javascript
"use strict";
const axios = require("axios");
const jwt = require("jsonwebtoken");
const formUrlEncoded = (x) =>
  Object.keys(x).reduce((p, c) => p + `&${c}=${encodeURIComponent(x[c])}`, "");
const allRepo = async function (params,model) {
  const data = await getAllRepo({
    model,
    token: params.token,
    token_pass: params.token_pass,
    before:params.before,
    after:params.after,
  });

  if (data&&data.nodes.length>0) {
    return {
      data,
    };
  } else {
    return {
      data: [],
    };
  }
};
const forSellRepo = async function (params,model) {
  const data = await getForSellRepo({
    model,
    token: params.token,
    token_pass: params.token_pass,
  });

  if (data&&data.length>0) {
    return {
      data,
    };
  } else {
    return {
      data: [],
    };
  }
};
const ownedRepo = async function (params,model) {
  const data = await getOwnedRepo({
    model,
    token: params.token,
    token_pass: params.token_pass,
  });

  if (data&&data.length>0) {
    return {
      data,
    };
  } else {
    return {
      data: [],
    };
  }
};

const profile = async function (params,model) {
  const data = await getProfile({
    model,
    token: params.token,
    token_pass: params.token_pass,
  });

  if (data) {
    return {
      data: data.data.viewer,
    };
  } else {
    return {
      data: {},
    };
  }
};

async function getProfile({ model, token_pass, token }) {
  const { access_token } = jwt.verify(token, token_pass);
  const _user=await model.user.findOne({where:{access_token}})
  
  if (_user) {
    const { data } = await axios({
      url: "https://api.github.com/graphql",
      headers: {
        Authorization: `token ${_user.access_token}`,
        Accept: "application/vnd.github.v3+json",
      },
      method: "POST",
      data: { query: "query { viewer { login,avatarUrl }}" },
    });
    return data;
  } else {
    return null;
  }
}

async function getAllRepo({ model, token_pass, token ,before,after}) {
  const { access_token } = jwt.verify(token, token_pass);
  const _user=await model.user.findOne({where:{access_token}})
  if (_user) {
    const { data } = await axios({
      url: "https://api.github.com/graphql",
      headers: {
        Authorization: `token ${_user.access_token}`,
        Accept: "application/vnd.github.v3+json",
      },
      method: "POST",
      data: {
        query: `{
          repositoryOwner(login: "${_user.username}") {
            repositories(${before||after?before?"last:5,":after?"first:5,":"":"first:5,"}${before?"before:\""+before+"\",":""}${after?"after:\""+after+"\",":""}affiliations:OWNER) {
           pageInfo {
        startCursor
        hasNextPage
        hasPreviousPage
        endCursor
      }
              nodes {
                isPrivate
                description
                name
                openGraphImageUrl
                url
                id
              }
            }
          }
        }
      `,
      },
    });
   
    const nodes = data.data.repositoryOwner.repositories;
    return nodes;
  } else {

    return [];
  }
}
async function getForSellRepo({ model, token_pass, token }) {
  const { access_token } = jwt.verify(token, token_pass);
  const _user=await model.user.findOne({where:{access_token}})
  
  if(_user){
    const {username}=_user;
    const forSell=await model.for_sell.findAll({where:{username}})
    return forSell;
  }else{
    return []
  }
  
}
async function getOwnedRepo({ model, token_pass, token }) {
  let _user
  if(token){
    const { access_token } = jwt.verify(token, token_pass);
   _user=await model.user.findOne({where:{access_token}})
  }
  
  if(_user){
    const {username}=_user;
    const ownedRepo=await model.owned_repo.findAll({where:{username}})
    return ownedRepo;
  }else{
    return []
  }
  
}
module.exports.profile = profile;
module.exports.forSellRepo = forSellRepo;
module.exports.ownedRepo = ownedRepo;
module.exports.allRepo = allRepo;
``` 

Now create a `utils/manage_access.js` to buy paypal and manage access to github repo :

```javascript
"use strict";
const axios = require("axios");
const jwt = require("jsonwebtoken");
function makeid(length) {
  var result = "";
  var characters =
    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
  var charactersLength = characters.length;
  for (var i = 0; i < length; i++) {
    result += characters.charAt(Math.floor(Math.random() * charactersLength));
  }
  return result;
}
const formUrlEncoded = (x) =>
  Object.keys(x).reduce((p, c) => p + `&${c}=${encodeURIComponent(x[c])}`, "");
const paypal = require("@paypal/checkout-server-sdk");
const buy_paypal = async function (params,model) {
  const random = makeid(5);
   
  const repo= await model.for_sell.findOne({where:{repo_id:params.id}})
  const paypalEmail= await model.paypal.findOne({where:{github_username:repo.username}})
    
  let clientId = params.paypal_client_id;
  let clientSecret = params.paypal_client_secret;
  let environment = new paypal.core.SandboxEnvironment(clientId, clientSecret);
  let client = new paypal.core.PayPalHttpClient(environment);
  let request = new paypal.orders.OrdersCreateRequest();
  request.requestBody({
    intent: "CAPTURE",
    purchase_units: [
      {
        amount: {
          currency_code: "USD",
          value: repo.amount,
        },
        payee: {
          email_address: paypalEmail.email,
        },
      },
    ],

    application_context: {
      return_url: `${params.return_url}/${params.token}/${params.id}/${random}`,
      cancel_url: params.cancel_url,
    },
  });

  let response = await client.execute(request);
  const [_transaction,created]=await model.transaction.findOrCreate({where:{random},defaults:{for_sell_id: response.result.id,
    token: params.token}})
    if(!created){
      await _transaction.update({for_sell_id:response.result.id,
        token:params.token})
    }
    
  return response;
};
const manage_access = async function (params,model) {
  const { token,id,random } = params;
  const { access_token } = jwt.verify(token, params.token_pass);
  const res=await model.user.findOne({where:{access_token}})
  if (res) {
    const transaction=await model.transaction.findOne({where:{random,token}})
    let clientId = params.paypal_client_id;
    let clientSecret = params.paypal_client_secret;
    let environment = new paypal.core.SandboxEnvironment(
      clientId,
      clientSecret
    );
    let client = new paypal.core.PayPalHttpClient(environment);
    const request = new paypal.orders.OrdersCaptureRequest(transaction.for_sell_id);
    request.requestBody({});
    let response = await client.execute(request);

    await transaction.destroy();
    
const privateRepo=await model.for_sell.findOne({where:{repo_id:id}})
    const repoOwner=await model.user.findOne({where:{username:privateRepo.username }})
    const paypalAcc=await model.paypal.findOne({where:{github_username:privateRepo.username }})
    const deleted = await axios({
      url: `https://api.github.com/repos/${privateRepo.username}/${privateRepo.name}/collaborators/${res.username}`,
      headers: {
        "Content-Type": "application/x-www-form-urlencoded",
        Authorization: `bearer ${repoOwner.access_token}`,
      },
      method: "DELETE",
    });
    const { data, status } = await axios({
      url: `https://api.github.com/repos/${privateRepo.username}/${privateRepo.name}/collaborators/${res.username}`,
      headers: {
        "Content-Type": "application/x-www-form-urlencoded",
        Authorization: `bearer ${repoOwner.access_token}`,
      },
      data: {
        permission: "admin",
      },
      method: "PUT",
    });
   
    if (status === 201) {
      let paypal = paypalAcc;
      let amount = Number(paypal.amount);
      amount += Number(privateRepo.amount);
      await paypal.update({amount});
      const {  username,repo_id, description,name,openGraphImageUrl,url,sell,amount:_amount } = privateRepo;
      const [owned,created]=await model.owned_repo.findOrCreate({where:{repo_id},defaults:{
        description,name,openGraphImageUrl,url,sell,amount:_amount,
        owner_username: username,
        username: res.username
      }})
     await owned.update({
      description,name,openGraphImageUrl,url,sell,amount:_amount,
      owner_username: username,
      username: res.username})
      
      if (created||owned) {
        return {
          headers: { location: data.html_url },
          statusCode: 302,
        };
        
      } else {
        return {
          headers: { location: `${params.frontend_url}/dashboard?error=not_created` },
          statusCode: 302,
        };
      
      }
    } else {
      
      return {
        headers: { location: `${params.frontend_url}/dashboard?error=status_not_201` },
        statusCode: 302,
      };
    }
  }
};
module.exports.buy_paypal = buy_paypal;
module.exports.manage_access = manage_access;

```

Make a `utils/paypal.js` in order for us to be able to save our sandbox paypal account :

```javascript
"use strict";
const axios = require("axios");
const jwt = require("jsonwebtoken");
const formUrlEncoded = (x) =>
  Object.keys(x).reduce((p, c) => p + `&${c}=${encodeURIComponent(x[c])}`, "");
const authorize_paypal = async function (params) {
   if (params.code) {
    const { access_token } = await authenticate({ params });
    const { emails } = await getEmail({ access_token });
    

    if (emails) {
      return {
        headers: { location: `${params.frontend_url}/callback/?email=${emails[0].value}` },
        statusCode: 302,
      };
    } else {
      return {
        headers: { location: `${params.frontend_url}/dashboard` },
        statusCode: 302,
      };
    }
  } else {
    return {
      headers: { location: `${params.frontend_url}/login` },
      statusCode: 302,
    };
  }
};

async function authenticate({ params }) {
  const { data } = await axios({
    url: "https://api.sandbox.paypal.com/v1/oauth2/token",
    headers: {
      "Content-Type": "application/x-www-form-urlencoded",
      Authorization: `Basic ${Buffer.from(
        `${params.paypal_client_id}:${params.paypal_client_secret}`
      ).toString("base64")}`,
    },
    data: formUrlEncoded({
      grant_type: "authorization_code",
      code: params.code,
    }),
    method: "POST",
  });
  return data;
}
async function getEmail({ access_token }) {
  const { data } = await axios({
    url:
      "https://api.sandbox.paypal.com/v1/identity/oauth2/userinfo?schema=paypalv1.1",
    headers: {
      Authorization: `Bearer ${access_token}`,
      "Content-Type": "application/json",
    },
    method: "GET",
  });
  return data;
}
const save_paypal=async function(params,model){

  const ok=await saveEmail({model,token_pass:params.token_pass,token:params.token,email:params.email})
  if(ok){
    return {status:true,message:"email saved"}
  }else{
    return {status:false,message:"email not saved"}
  }
}
async function saveEmail({ token_pass,token, model, email }) {
  const { access_token } = jwt.verify(token, token_pass);
  const _user=await model.user.findOne({where:{access_token}})
  if (_user) {
    const [_paypal,created]=await model.paypal.findOrCreate({where:{github_username:_user.username},defaults: {
      email,
      amount:0,
      disconnect:false
    }})
    if(!created){
      _paypal.disconnect=false;
      await _paypal.save()
      return true
    }else{
      return created;
    }
    
    
  } else {
    return false
  }
}
const get_paypal=async function(params,model){
  
  const ok=await getPaypal({model,token_pass:params.token_pass,token:params.token})
  if(ok){
    return {status:true,data:ok}
  }else{
    return {status:false,message:"error"}
  }
}
async function getPaypal({ model, token_pass, token }) {
  const { access_token } = jwt.verify(token, token_pass);
   const _user=await model.user.findOne({where:{access_token}})
  if(_user){
    const _paypal=await model.paypal.findOne({where:{github_username:_user.username}})
    return _paypal;          
  }else{
    return {status:false,data:[],message:"error token"}
  }
  
}
const disconnect_paypal=async function(params,model){

  const ok=await deletePaypal({model,token_pass:params.token_pass,token:params.token})
  if(ok){
    return {status:true,data:ok}
  }else{
    return {status:false,message:"error"}
  }
}
async function deletePaypal({ model, token_pass, token }) {
  const { access_token } = jwt.verify(token, token_pass);
  const _user=await model.user.findOne({where:{access_token}})
  
await model.for_sell.update({
sell: "UNLIST",
}, {
  where: {
    username:_user.username
  }
});
  
  if(_user){
    const _paypal=await model.paypal.findOne({where:{github_username:_user.username}})
    _paypal.disconnect=true;
    _paypal.save()
    return {status:true,message:"success"}
          
  }else{
    return {status:false,data:[],message:"error token"}
  }
  
}
module.exports.authorize_paypal = authorize_paypal;
module.exports.save_paypal = save_paypal;
module.exports.get_paypal = get_paypal;
module.exports.disconnect_paypal = disconnect_paypal;

```
And last but not least create a `utils/sell_repo.js` to sell the repo

```javascript
const axios = require("axios");
const jwt = require("jsonwebtoken");
const sell_repo = async function (params,model) {
    
  
    const data = await sellRepo({
      model,
      token: params.token,
      token_pass: params.token_pass,
      name:params.name,
      amount:params.amount
      
    });
  
    if (data && data.length>0) {
      return {
        data
      };
    } else {
      return {
        data,
      };
    }
  };
  const list_repo = async function (params,model) {
    
  
    const data = await listRepo({
      model,
      token: params.token,
      token_pass: params.token_pass,
      item:params.item,
      
      
    });
  
    if (data && data.length>0) {
      return {
        data
      };
    } else {
      return {
        data,
      };
    }
  };
  const unlist_repo = async function (params,model) { 
  
    const data = await unlistRepo({
      model,
      token: params.token,
      token_pass: params.token_pass,
      id:params.id,
      
    });
  
    if (data && data.length>0) {
      return {
        data
      };
    } else {
      return {
        data,
      };
    }
  };
  const for_sale_repo = async function (params,model) {
   
  
    const data = await forSaleRepo({
      model,
      token: params.token,
      token_pass: params.token_pass,
    });
  
    if (data && data.data.length>0) {
      return {
        data
      };
    } else {
      return {
        data,
      };
    }
  };
  async function repo_detail(params,model){
return (await model.for_sell.findOne({where:{username:params.username,name:params.name}}))
  }
  async function getRepoDetail({_user, name}) {
      if (_user) {
      const { data } = await axios({
        url: "https://api.github.com/graphql",
        headers: {
          Authorization: `token ${_user.access_token}`,
          Accept: "application/vnd.github.v3+json",
        },
        method: "POST",
        data: {
          query: `{repository(name:"${name}",owner:"${_user.username}"){
            description
                           name
                           openGraphImageUrl
                           url
                           id
                           isPrivate
         }}
        `,
        },
      });
      const repository = data.data.repository
      return repository;
    } else {
  
      return undefined;
    }
  }
  async function sellRepo({ model, token_pass, token,name,amount}) {
    const { access_token } = jwt.verify(token, token_pass);
      const _user=await model.user.findOne({where:{access_token}})    
    if(_user){
      let repo = await getRepoDetail({_user,name})
      if(repo){
        const {id,...repoDetail}=repo;
        const [_repo, created] = await model.for_sell.findOrCreate({
          where: { repo_id: repo.id },
          defaults: {
            ...repoDetail,
            sell:"SELL",
            amount:amount
          }
        });
        const updated=await _repo.update({...repoDetail,
          sell:"SELL",
          amount:amount})
        if(updated||created){
          const forSale=await model.for_sell.findAll({where:{username:_user.username}})
          return forSale
        }else{
          return {status:false,data:[],message:"error selling"}  
        }
        
      }else{
        return {status:false,data:[],message:"error selling"}
      }
      
    }else{
      return {status:false,data:[],message:"error token"}
    }
    
  }
  async function listRepo({ model, token_pass, token,item }) {
    const { access_token } = jwt.verify(token, token_pass);
    const _user=await model.user.findOne({where:{access_token}})
    if(_user){
      const {id,...other}=item
      const [repo,created]=await model.for_sell.findOrCreate({where:{repo_id:id},defaults:{
...other,
sell:"UNLIST",
amount:0,
username:_user.username
      }})
     if(repo){
       const updated=await repo.update({...other,sell:"UNLIST",amount:0,username:_user.username})
       if(created||updated){
        const repoAll=await model.for_sell.findAll({where:{username:_user.username}})
         return repoAll
     }else{
       return {status:false,data:[],message:"error list"}
     }
     }
      
      
    }else{
      return {status:false,data:[],message:"error token"}
    }
    
  }
  async function unlistRepo({ model, token_pass, token,id }) {
    const { access_token } = jwt.verify(token, token_pass);
    const _user=await model.user.findOne({where:{access_token}})
    if(_user){
      const repo=await model.for_sell.findOne({where:{repo_id:id}})
      if(repo){
        repo.sell="UNLIST";
        await repo.save()
        const repoAll=await model.for_sell.findAll({where:{username:_user.username}})
        return repoAll
      }else{
        return {status:false,data:[],message:"error unlist"}
      }
      
    }else{
      return {status:false,data:[],message:"error token"}
    }
    
  }
  async function forSaleRepo({ model, token_pass, token }) {
    let _user;
    if(token){
      const { access_token } = jwt.verify(token, token_pass);
      _user=await model.user.findOne({where:{access_token}})
    }
    
     const repo = await model.for_sell.findAll({where:{sell:"SELL"}})
      return {username:_user?_user.username:null,data:repo}   
  }
  module.exports.sell_repo = sell_repo;
  module.exports.unlist_repo = unlist_repo;
  module.exports.for_sale_repo = for_sale_repo;
  module.exports.list_repo = list_repo;
  module.exports.repo_detail = repo_detail;
```
If you have done all of that now create an `.env` file and write this :

```
frontend_url=<our static nuxtjs frontend url>
github_client_id=<github client id>
github_client_secret=<github client secret>
paypal_client_id=<paypal client id>
paypal_client_secret=<paypal client secret>
token_pass=<token pass for jwt>
return_url=<https://your_app_platform_url/manage-access>
cancel_url=<https://frontend_url/dashboard?cancel=message>
```
Now you've successfully create the backend of our app the step 3 would be to deploy this app into app platform