Files
anonymous_github/src/server/routes/conference.ts
T

296 lines
8.2 KiB
TypeScript

import * as express from "express";
import AnonymousError from "../../core/AnonymousError";
import Conference from "../../core/Conference";
import ConferenceModel from "../../core/model/conference/conferences.model";
import { ensureAuthenticated } from "./connection";
import { handleError, getUser, isOwnerOrAdmin } from "./route-utils";
import { IConferenceDocument } from "../../core/model/conference/conferences.types";
const router = express.Router();
// user needs to be connected for all user API
router.use(ensureAuthenticated);
const plans = [
{
id: "free_conference",
name: "Free",
pricePerRepo: 0,
storagePerRepo: -1,
description: `<li><strong>Quota is deducted from user account</strong></li>
<li>No-download</li>
<li>Conference dashboard</li>`,
},
{
id: "premium_conference",
name: "Premium",
pricePerRepo: 0.5,
storagePerRepo: 500 * 8 * 1024,
description: `<li>500Mo / repository</li>
<li>Repository download</li>
<li>Conference dashboard</li>`,
},
{
id: "unlimited_conference",
name: "Unlimited",
pricePerRepo: 3,
storagePerRepo: 0,
description: `<li><strong>Unlimited</strong> repository size</li>
<li>Repository download</li>
<li>Conference dashboard</li>`,
},
];
router.get("/plans", async (req: express.Request, res: express.Response) => {
res.json(plans);
});
router.get("/", async (req: express.Request, res: express.Response) => {
try {
const user = await getUser(req);
const conferences = await Promise.all(
(
await ConferenceModel.find({
owners: { $in: user.model.id },
})
).map(async (data) => {
const conf = new Conference(data);
if (data.endDate < new Date() && data.status == "ready") {
await conf.expire();
}
return conf;
})
);
res.json(conferences.map((conf) => conf.toJSON()));
} catch (error) {
handleError(error, res, req);
}
});
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function validateConferenceForm(conf: any) {
if (!conf.name)
throw new AnonymousError("conf_name_missing", {
object: conf,
httpStatus: 400,
});
if (!conf.conferenceID)
throw new AnonymousError("conf_id_missing", {
object: conf,
httpStatus: 400,
});
if (!conf.startDate)
throw new AnonymousError("conf_start_date_missing", {
object: conf,
httpStatus: 400,
});
if (!conf.endDate)
throw new AnonymousError("conf_end_date_missing", {
object: conf,
httpStatus: 400,
});
if (new Date(conf.startDate) > new Date(conf.endDate))
throw new AnonymousError("conf_start_date_invalid", {
object: conf,
httpStatus: 400,
});
if (new Date() > new Date(conf.endDate))
throw new AnonymousError("conf_end_date_invalid", {
object: conf,
httpStatus: 400,
});
if (plans.filter((p) => p.id == conf.plan.planID).length != 1)
throw new AnonymousError("invalid_plan", {
object: conf,
httpStatus: 400,
});
const plan = plans.filter((p) => p.id == conf.plan.planID)[0];
if (plan.pricePerRepo > 0) {
const billing = conf.billing;
if (!billing)
throw new AnonymousError("billing_missing", {
object: conf,
httpStatus: 400,
});
if (!billing.name)
throw new AnonymousError("billing_name_missing", {
object: conf,
httpStatus: 400,
});
if (!billing.email)
throw new AnonymousError("billing_email_missing", {
object: conf,
httpStatus: 400,
});
if (!billing.address)
throw new AnonymousError("billing_address_missing", {
object: conf,
httpStatus: 400,
});
if (!billing.city)
throw new AnonymousError("billing_city_missing", {
object: conf,
httpStatus: 400,
});
if (!billing.zip)
throw new AnonymousError("billing_zip_missing", {
object: conf,
httpStatus: 400,
});
if (!billing.country)
throw new AnonymousError("billing_country_missing", {
object: conf,
httpStatus: 400,
});
}
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export function applyConferenceForm(
model: IConferenceDocument,
body: any,
isNew: boolean
) {
model.name = body.name;
model.startDate = new Date(body.startDate);
model.endDate = new Date(body.endDate);
model.status = "ready";
model.url = body.url;
model.options = body.options;
if (isNew) model.repositories = [];
}
router.post(
"/{:conferenceID}",
async (req: express.Request, res: express.Response) => {
try {
const user = await getUser(req);
let model: IConferenceDocument = new ConferenceModel();
if (req.params.conferenceID) {
const queryModel = await ConferenceModel.findOne({
conferenceID: req.params.conferenceID,
});
if (!queryModel) {
throw new AnonymousError("conference_not_found", {
httpStatus: 404,
});
}
model = queryModel;
isOwnerOrAdmin(model.owners, user);
}
validateConferenceForm(req.body);
applyConferenceForm(model, req.body, !req.params.conferenceID);
if (!req.params.conferenceID) {
model.owners.push(user.model.id);
model.conferenceID = req.body.conferenceID;
model.plan = {
planID: req.body.plan.planID,
pricePerRepository: plans.filter(
(p) => p.id == req.body.plan.planID
)[0].pricePerRepo,
quota: {
size: plans.filter((p) => p.id == req.body.plan.planID)[0]
.storagePerRepo,
file: 0,
repository: 0,
},
};
if (req.body.billing)
model.billing = {
name: req.body.billing.name,
email: req.body.billing.email,
address: req.body.billing.address,
address2: req.body.billing.address2,
city: req.body.billing.city,
zip: req.body.billing.zip,
country: req.body.billing.country,
vat: req.body.billing.vat,
};
}
await model.save();
res.send("ok");
} catch (error) {
if (
error instanceof Error &&
error.message?.indexOf(" duplicate key") > -1
) {
return handleError(
new AnonymousError("conf_id_used", {
object: req.params.conferenceID,
httpStatus: 400,
}),
res
);
}
handleError(error, res, req);
}
}
);
router.get(
"/:conferenceID",
async (req: express.Request, res: express.Response) => {
try {
const data = await ConferenceModel.findOne({
conferenceID: req.params.conferenceID,
});
if (!data)
throw new AnonymousError("conf_not_found", {
object: req.params.conferenceID,
httpStatus: 404,
});
const user = await getUser(req);
const conference = new Conference(data);
try {
isOwnerOrAdmin(conference.ownerIDs, user);
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const o: any = conference.toJSON();
o.repositories = (await conference.repositories()).map((r) =>
r.toJSON()
);
res.json(o);
} catch {
return res.json({
conferenceID: conference.conferenceID,
name: conference.name,
url: conference.url,
startDate: conference.startDate,
endDate: conference.endDate,
options: conference.options,
});
}
} catch (error) {
handleError(error, res, req);
}
}
);
router.delete(
"/:conferenceID",
async (req: express.Request, res: express.Response) => {
try {
const user = await getUser(req);
const data = await ConferenceModel.findOne({
conferenceID: req.params.conferenceID,
});
if (!data)
throw new AnonymousError("conf_not_found", {
object: req.params.conferenceID,
httpStatus: 400,
});
const conference = new Conference(data);
isOwnerOrAdmin(conference.ownerIDs, user);
await conference.remove();
res.send("ok");
} catch (error) {
handleError(error, res, req);
}
}
);
export default router;