{"size": 9336, "ext": "js", "max_stars_repo_path": "src/routes/app/index.js", "max_stars_repo_name": "data-studio/web-api", "max_stars_repo_stars_event_min_datetime": null, "max_stars_repo_stars_event_max_datetime": null, "max_issues_repo_path": "src/routes/app/index.js", "max_issues_repo_name": "data-studio/web-api", "max_issues_repo_issues_event_min_datetime": "2019-02-21T21:31:01.000Z", "max_issues_repo_issues_event_max_datetime": "2019-02-21T21:31:01.000Z", "max_forks_repo_path": "src/routes/app/index.js", "max_forks_repo_name": "data-studio/web-api", "max_forks_repo_forks_event_min_datetime": null, "max_forks_repo_forks_event_max_datetime": null}
{"max_stars_count": null, "max_issues_count": 1, "max_forks_count": null, "avg_line_length": 30.6098360656, "max_line_length": 108, "alphanum_fraction": 0.5606255356}
/**
 * Data Studio by Eviratec
 * Copyright (c) 2017 - 2019 Callan Peter Milne
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
 * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
 * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 * PERFORMANCE OF THIS SOFTWARE.
 */
"use strict";

const v4uuid = require("uuid/v4");

function requireAuthorization (req, res, next) {
  if (!req.authorized) {
    return res.sendStatus(403);
  }
  next();
}

module.exports = function (dataStudio) {

  const api = dataStudio.expressApp;
  const db = dataStudio.db;
  const events = dataStudio.events;
  const authz = dataStudio.authz;

  api.get("/app/:appId", requireAuthorization, function (req, res) {
    if (null === req.appModel) {
      return res.sendStatus(404);
    }
    authz.verifyOwnership(req.path, req.authUser.get("Id"))
      .then(function () {
        res.status(200).send(req.appModel);
      })
      .catch(function (err) {
        res.sendStatus(404);
      });
  });

  api.put("/app/:appId", requireAuthorization, function (req, res) {
    return res.sendStatus(404);
  });

  api.get("/apps/all", requireAuthorization, function (req, res) {
    db.fetchAppsByUserId(req.authUser.get("Id"))
      .then(function (apps) {
        res.status(200).send(apps);
      })
      .catch(function (err) {
        res.status(500).send({ ErrorMsg: err.message });
      });
  });

  api.post("/apps", requireAuthorization, function (req, res) {
    let App = db.App;
    let newAppId = v4uuid();
    let newApp = {
      Id: newAppId,
      UserId: req.authUser.get("Id"),
      Name: req.body.Name || "Un-named App",
      Created: Math.floor(Date.now()/1000),
    };
    App.forge(newApp)
      .save(null, {method:"insert"})
      .then(function (app) {
        let uri = `/app/${newAppId}`;
        events.emit("resource:created", uri, req.authUser.get("Id"));
        res.returnNewObject(app);
      })
      .catch(function (err) {
        console.log(err);
        res.status(400).send({ ErrorMsg: err.message });
      });
  });

  api.get("/app/:appId", requireAuthorization, function (req, res) {
    if (req.appModel.get("UserId") !== req.authUser.get("Id")) {
      return res.sendStatus(403);
    }
    db.fetchDetailedAppById(req.appModel.get("Id"))
      .then(function (app) {
        res.status(200).send(app);
      })
      .catch(function (err) {
        res.status(400).send({
          Error: err.message,
        });
      });
  });

  api.delete("/app/:appId", requireAuthorization, function (req, res) {
    if (req.appModel.get("UserId") !== req.authUser.get("Id")) {
      return res.sendStatus(403);
    }
    req.appModel.save({"Deleted": Math.floor(Date.now()/1000)}, {patch: true})
      .then(function () {
        res.sendStatus(204);
      })
      .catch(function (err) {
        console.log(err);
        res.sendStatus(500);
      });

  });


  [
    {id: "schemas", fetch: "fetchAppSchemasByAppId"},
    {id: "apis", fetch: "fetchAppApisByAppId"},
    {id: "clients", fetch: "fetchAppClientsByAppId"},
  ].forEach(x => {

    let tId = x.id;
    let tFn = x.fetch;

    api.get(`/app/:appId/${tId}`, requireAuthorization, function (req, res) {
      if (req.appModel.get("UserId") !== req.authUser.get("Id")) {
        return res.sendStatus(403);
      }
      db[tFn](req.appModel.get("Id"))
        .then(function (schemas) {
          res.status(200).send(schemas);
        })
        .catch(function (err) {
          res.status(500).send({ ErrorMsg: err.message });
        });
    });

  });

  api.get("/app/:appId/:subTypeName/:subTypeId", requireAuthorization, function (req, res) {
    let t = {
      "clients": "client",
      "apis": "api",
      "schemas": "schema",
    }
    let Client = db.Client;
    let Api = db.Api;
    let AppSchema = db.AppSchema;
    let subTypeName = req.subTypeName;
    let subTypeId = req.subTypeId;
    let appId = req.appModel.get("Id");
    let newAppThingId = v4uuid();
    let newAppThing;
    switch (subTypeName) {
      case "client":
        db.fetchClientById(subTypeId)
          .then(function (client) {
            authz.verifyOwnership(req.path, req.authUser.get("Id"))
              .then(function () {
                res.status(200).send(client);
              })
              .catch(function (err) {
                res.status(404).send();
              });
          })
          .catch(function (err) {
            console.log(err);
            res.status(400).send({ ErrorMsg: err.message });
          });
        break;
      case "api":
        db.fetchApiById(subTypeId)
          .then(function (api) {
            authz.verifyOwnership(req.path, req.authUser.get("Id"))
              .then(function () {
                res.status(200).send(api);
              })
              .catch(function (err) {
                res.status(404).send();
              });
          })
          .catch(function (err) {
            console.log(err);
            res.status(400).send({ ErrorMsg: err.message });
          });
        break;
      case "schema":
        db.fetchSchemaById(subTypeId)
          .then(function (schema) {
            authz.verifyOwnership(req.path, req.authUser.get("Id"))
              .then(function () {
                res.status(200).send(schema);
              })
              .catch(function (err) {
                res.status(404).send();
              });
          })
          .catch(function (err) {
            console.log(err);
            res.status(400).send({ ErrorMsg: err.message });
          });
        break;
    }
  });

  api.post("/app/:appId/:subTypeName", requireAuthorization, function (req, res) {
    let t = {
      "clients": "client",
      "apis": "api",
      "schemas": "schema",
    }
    let Client = db.Client;
    let Api = db.Api;
    let AppSchema = db.AppSchema;
    let subTypeName = req.subTypeName;
    let appId = req.appModel.get("Id");
    let newAppThingId = v4uuid();
    let newAppThing;
    switch (subTypeName) {
      case "clients":
        newAppThing = new Client({
          Id: newAppThingId,
          AppId: appId,
          Name: req.body.Name || "NewClient",
          Created: Math.floor(Date.now()/1000),
        });
        break;
      case "apis":
        newAppThing = new Api({
          Id: newAppThingId,
          AppId: appId,
          Name: req.body.Name || "NewApi",
          Created: Math.floor(Date.now()/1000),
        });
        break;
      case "schemas":
        newAppThing = new AppSchema({
          Id: newAppThingId,
          AppId: appId,
          Name: req.body.Name || "NewSchema",
          Ref: req.body.Ref || "#" + req.body.Name,
          Created: Math.floor(Date.now()/1000),
        });
        break;
    }
    newAppThing.save()
      .then(function (appThing) {
        let uri = `/app/${appId}/${t[subTypeName]}/${appThing.get("Id")}`;
        events.emit("resource:created", uri, req.authUser.get("Id"));
        events.emit("resource:created", `/${t[subTypeName]}/${appThing.get("Id")}`, req.authUser.get("Id"));
        res.returnNewObject(appThing);
      })
      .catch(function (err) {
        res.status(400).send({ ErrorMsg: err.message });
      });
  });

  api.delete("/app/:appId/schema/:schemaId", requireAuthorization, function (req, res) {
    authz.verifyOwnership(req.path, req.authUser.get("Id"))
      .then(function () {
        req.appSchemaModel.save({"Deleted": Math.floor(Date.now()/1000)}, {patch: true})
          .then(function () {
            res.sendStatus(204);
          })
          .catch(function (err) {
            console.log(err);
            res.sendStatus(500);
          });
      })
      .catch(function (err) {
        res.status(400).send();
      });
  });

  api.get("/app/:appId/api/:apiId", requireAuthorization, function (req, res) {
    if (req.appModel.get("UserId") !== req.authUser.get("Id")) {
      return res.sendStatus(403);
    }
    if (req.apiModel.get("AppId") !== req.appModel.get("Id")) {
      return res.sendStatus(400);
    }
    res.status(200).send(req.apiModel);
  });

  api.get("/app/:appId/client/:clientId", requireAuthorization, function (req, res) {
    if (req.appModel.get("UserId") !== req.authUser.get("Id")) {
      return res.sendStatus(403);
    }
    if (req.clientModel.get("AppId") !== req.appModel.get("Id")) {
      return res.sendStatus(400);
    }
    res.status(200).send(req.clientModel);
  });

  api.get("/app/:appId/schema/:appSchemaId", requireAuthorization, function (req, res) {
    if (req.appModel.get("UserId") !== req.authUser.get("Id")) {
      return res.sendStatus(403);
    }
    if (req.appSchemaModel.get("AppId") !== req.appModel.get("Id")) {
      return res.sendStatus(400);
    }
    res.status(200).send(req.appSchemaModel);
  });

};
