DEV Community

spiritupbro
spiritupbro

Posted on

Step 2 - Create Backend Using Expressjs

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


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

mkdir opensource-marketplace-backend
cd opensource-marketplace-backend
npx express-generator
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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

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 }
    }
  }
}


Enter fullscreen mode Exit fullscreen mode

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 :

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
Enter fullscreen mode Exit fullscreen mode

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

version: '3'
services:
  database:
    image: "postgres" 
    ports:
      - "5432:5432"
    env_file:
      - database.env 
    volumes:
      - database-data:/var/lib/postgresql/data/ 
volumes:
  database-data: 
Enter fullscreen mode Exit fullscreen mode

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 :

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

Enter fullscreen mode Exit fullscreen mode

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 :

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;

Enter fullscreen mode Exit fullscreen mode

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 :

"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;

  }
}


Enter fullscreen mode Exit fullscreen mode

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

"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;
Enter fullscreen mode Exit fullscreen mode

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

"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;

Enter fullscreen mode Exit fullscreen mode

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

"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;

Enter fullscreen mode Exit fullscreen mode

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

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;
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

Now you've successfully create the backend of our app the step 3 would be to deploy this app into app platform

Top comments (0)