mirror of
https://github.com/tdurieux/anonymous_github.git
synced 2026-10-20 06:37:23 +02:00
296 lines
8.2 KiB
TypeScript
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;
|