Skip to content

Commit

Permalink
feat: implement logging (#31)
Browse files Browse the repository at this point in the history
  • Loading branch information
Abhijna-Raghavendra authored Feb 14, 2024
2 parents 708ba40 + 443de7b commit 2dd2226
Show file tree
Hide file tree
Showing 10 changed files with 241 additions and 142 deletions.
2 changes: 1 addition & 1 deletion docker/Dockerfile.backend
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@ COPY . ./

RUN deno cache src/backend/dependencies.ts

CMD ["run", "--allow-net", "--allow-env", "--allow-read","--allow-run","src/backend/server.ts"]
CMD ["run", "--allow-net", "--allow-env", "--allow-read","--allow-run","--allow-sys","src/backend/server.ts"]
3 changes: 2 additions & 1 deletion src/backend/.env.sample
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
GITHUB_OAUTH_CLIENT_ID=...
GITHUB_OAUTH_CLIENT_SECRET=...
MONGO_API_KEY=...
MONGO_APP_ID=...
MONGO_APP_ID=...
SENTRY_DSN=...
3 changes: 2 additions & 1 deletion src/backend/auth/github.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Context } from "../dependencies.ts";
import { Context, Sentry } from "../dependencies.ts";
import { checkUser } from "../db.ts";
import { checkJWT, createJWT } from "../utils/jwt.ts";

Expand Down Expand Up @@ -27,6 +27,7 @@ async function githubAuth(ctx: Context, id: string, secret: string) {
ctx.response.headers.set("Access-Control-Allow-Origin", "*");
if (status.matchedCount == 1) {
const id_jwt = await createJWT(githubId);
Sentry.captureMessage("User " + githubId + " logged in", "info");
ctx.response.body = id_jwt;
} else {
ctx.response.body = "not authorized";
Expand Down
177 changes: 45 additions & 132 deletions src/backend/db.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import getGithubUser from "./utils/github-user.ts";
import { Context, exec } from "./dependencies.ts";
import { Context, exec, Sentry } from "./dependencies.ts";
import dockerize from "./utils/container.ts";
import { checkJWT } from "./utils/jwt.ts";
import DfContentMap from "./types/maps_interface.ts";

const DATA_API_KEY = Deno.env.get("MONGO_API_KEY")!;
const APP_ID = Deno.env.get("MONGO_APP_ID");

const BASE_URI =
`https://ap-south-1.aws.data.mongodb-api.com/app/${APP_ID}/endpoint/data/v1`;
const DATA_SOURCE = "domain-forge-demo-db";
Expand All @@ -20,185 +22,96 @@ const options = {
body: "",
};

const MONGO_URLs = {
update: new URL(`${BASE_URI}/action/updateOne`),
find: new URL(`${BASE_URI}/action/find`),
insert: new URL(`${BASE_URI}/action/insertOne`),
delete: new URL(`${BASE_URI}/action/deleteOne`),
};

// Function to update access token on db if user exists
async function checkUser(accessToken: string) {
const auth_query = {
const githubId = await getGithubUser(accessToken);

const query = {
collection: "user_auth",
database: DATABASE,
dataSource: DATA_SOURCE,
filter: {},
update: {},
};
const githubId = await getGithubUser(accessToken);
auth_query.filter = { "githubId": githubId };
auth_query.update = {
$set: {
"githubId": githubId,
"authToken": accessToken,
filter: { "githubId": githubId },
update: {
$set: {
"githubId": githubId,
"authToken": accessToken,
},
},
};
const update_url = new URL(`${BASE_URI}/action/updateOne`);
options.body = JSON.stringify(auth_query);
const status_resp = await fetch(update_url.toString(), options);

options.body = JSON.stringify(query);

const status_resp = await fetch(MONGO_URLs.update.toString(), options);
const status = await status_resp.json();
return { status, githubId };
}

async function getMaps(ctx: Context) {
console.log("get maps");
const author = ctx.request.url.searchParams.get("user");
const token = ctx.request.url.searchParams.get("token");
if (author != await checkJWT(token)) {
ctx.throw(401);
}
// Get all content maps corresponding to user
async function getMaps(author: string) {
const query = {
collection: "content_maps",
database: DATABASE,
dataSource: DATA_SOURCE,
filter: { "author": author },
};
options.body = JSON.stringify(query);
const url = new URL(`${BASE_URI}/action/find`);
const resp = await fetch(url.toString(), options);
const resp = await fetch(MONGO_URLs.find.toString(), options);
const data = await resp.json();
ctx.response.headers.set("Access-Control-Allow-Origin", "*");
ctx.response.body = data.documents;
return data;
}
async function addMaps(ctx: Context) {
if (!ctx.request.hasBody) {
ctx.throw(415);
}
let document,
author: string,
token: string,
env_content: string,
static_content: string,
stack: string,
port: string,
build_cmds: string;
const body = await ctx.request.body().value;
try {
document = JSON.parse(body);
author = document.author;
token = document.token;
//env_contents not getting saved to db
env_content = document.env_content;
static_content = document.static_content;
stack = document.stack;
port = document.port;
build_cmds = document.build_cmds;
delete document.token;
delete document.port;
delete document.build_cmds;
delete document.stack;
delete document.env_content;
delete document.static_content;
} catch (e) {
document = body;
author = document.author;
token = document.token;
env_content = document.env_content;
static_content = document.static_content;
stack = document.stack;
port = document.port;
build_cmds = document.build_cmds;
delete document.token;
delete document.port;
delete document.build_cmds;
delete document.stack;
delete document.env_content;
delete document.static_content;
}

if (author != await checkJWT(token)) {
ctx.throw(401);
}
let query = {
// Add content maps
async function addMaps(document: DfContentMap) {
const query = {
collection: "content_maps",
database: DATABASE,
dataSource: DATA_SOURCE,
filter: { "subdomain": document.subdomain },
};
options.body = JSON.stringify(query);
let url = new URL(`${BASE_URI}/action/find`);
let resp = await fetch(url.toString(), options);

let resp = await fetch(MONGO_URLs.find.toString(), options);
let data = await resp.json();

if (data.documents.length == 0) {
let query = {
const query = {
collection: "content_maps",
database: DATABASE,
dataSource: DATA_SOURCE,
document: document,
};

options.body = JSON.stringify(query);
url = new URL(`${BASE_URI}/action/insertOne`);
resp = await fetch(url.toString(), options);
resp = await fetch(MONGO_URLs.insert.toString(), options);
data = await resp.json();
ctx.response.headers.set("Access-Control-Allow-Origin", "*");
if (document.resource_type === "URL") {
await exec(
`bash -c "echo 'bash ../../src/backend/utils/automate.sh -u ${document.resource} ${document.subdomain}' > /hostpipe/pipe"`,
);
} else if (document.resource_type === "PORT") {
await exec(
`bash -c "echo 'bash ../../src/backend/utils/automate.sh -p ${document.resource} ${document.subdomain}' > /hostpipe/pipe"`,
);
} else if (document.resource_type === "GITHUB" && static_content == "Yes") {
await exec(
`bash -c "echo 'bash ../../src/backend/utils/container.sh -s ${document.subdomain} ${document.resource} ${env_content}' > /hostpipe/pipe"`,
);
} else if (document.resource_type === "GITHUB" && static_content == "No") {
let dockerfile = dockerize(stack, port, build_cmds);
await exec(
`bash -c "echo 'bash ../../src/backend/utils/container.sh -g ${document.subdomain} ${document.resource} ${env_content} ${dockerfile} ${port}' > /hostpipe/pipe"`,
);
}

(data.insertedId !== undefined)
? ctx.response.body = { "status": "success" }
: ctx.response.body = { "status": "failed" };
} else {
ctx.response.headers.set("Access-Control-Allow-Origin", "*");

ctx.response.body = { "status": "failed" };
return (data.insertedId !== undefined);
} else {
return false;
}
}

async function deleteMaps(ctx: Context) {
if (!ctx.request.hasBody) {
ctx.throw(415);
}
let document;
const body = await ctx.request.body().value;
try {
document = JSON.parse(body);
} catch (e) {
document = body;
}
const author = document.author;
const token = document.token;
delete document.token;
if (author != await checkJWT(token)) {
ctx.throw(401);
}
// Delete content maps
async function deleteMaps(document: DfContentMap) {
const query = {
collection: "content_maps",
database: DATABASE,
dataSource: DATA_SOURCE,
filter: document,
};
options.body = JSON.stringify(query);
const url = new URL(`${BASE_URI}/action/deleteOne`);
const resp = await fetch(url.toString(), options);

const resp = await fetch(MONGO_URLs.delete.toString(), options);
const data = await resp.json();
if (data.deletedCount) {
await exec(
`bash -c "echo 'bash ../../src/backend/utils/delete.sh ${document.subdomain}' > /hostpipe/pipe"`,
);
}

ctx.response.headers.set("Access-Control-Allow-Origin", "*");
ctx.response.body = data;
return data;
}

export { addMaps, checkUser, deleteMaps, getMaps };

18 changes: 16 additions & 2 deletions src/backend/dependencies.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,24 @@
import {
Application,
Context,
isHttpError,
Router,
Status,
} from "https://deno.land/x/[email protected]/mod.ts";
import { Session } from "https://deno.land/x/[email protected]/mod.ts";
import { create, verify } from "https://deno.land/x/[email protected]/mod.ts";
import { exec } from "https://deno.land/x/exec/mod.ts";
import { exec } from "https://deno.land/x/[email protected]/mod.ts";
import * as Sentry from "npm:@sentry/node";

export { Application, Context, create, exec, Router, Session, verify };
export {
Application,
Context,
create,
exec,
isHttpError,
Router,
Sentry,
Session,
Status,
verify,
};
90 changes: 90 additions & 0 deletions src/backend/main.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import { Context, Sentry } from "./dependencies.ts";
import { addScript, deleteScript } from "./scripts.ts";
import { checkJWT } from "./utils/jwt.ts";
import { addMaps, deleteMaps, getMaps } from "./db.ts";

async function getSubdomains(ctx: Context) {
const author = ctx.request.url.searchParams.get("user");
const token = ctx.request.url.searchParams.get("token");
if (author != await checkJWT(token!)) {
ctx.throw(401);
}
const data = await getMaps(author);
ctx.response.headers.set("Access-Control-Allow-Origin", "*");
ctx.response.body = data.documents;
}

async function addSubdomain(ctx: Context) {
if (!ctx.request.hasBody) {
ctx.throw(415);
}
let document;
const body = await ctx.request.body().value;
try {
document = JSON.parse(body);
} catch (e) {
document = body;
}
const copy = document;
const token = document.token;
delete document.token;
delete document.port;
delete document.build_cmds;
delete document.stack;
delete document.env_content;
delete document.static_content;
if (document.author != await checkJWT(token)) {
ctx.throw(401);
}
const success: boolean = await addMaps(document);
ctx.response.headers.set("Access-Control-Allow-Origin", "*");

if (success) {
await addScript(
document,
copy.env_content,
copy.static_content,
copy.stack,
copy.port,
copy.build_cmds,
);
ctx.response.body = { "status": "success" };
Sentry.captureMessage(
"User " + document.author + " added subdomain " + document.subdomain,
"info",
);
} else {
ctx.response.body = { "status": "failed" };
}
}

async function deleteSubdomain(ctx: Context) {
if (!ctx.request.hasBody) {
ctx.throw(415);
}
let document;
const body = await ctx.request.body().value;
try {
document = JSON.parse(body);
} catch (e) {
document = body;
}
const author = document.author;
const token = document.token;
delete document.token;
if (author != await checkJWT(token)) {
ctx.throw(401);
}
const data = await deleteMaps(document);
if (data.deletedCount) {
deleteScript(document);
Sentry.captureMessage(
"User " + document.author + " deleted subdomain " + document.subdomain,
"info",
);
}
ctx.response.headers.set("Access-Control-Allow-Origin", "*");
ctx.response.body = data;
}

export { addSubdomain, deleteSubdomain, getSubdomains };
Loading

0 comments on commit 2dd2226

Please sign in to comment.