Restructuring the Project
Updating dependencies
This commit is contained in:
191
Backend/src/api/admin/client.ts
Normal file
191
Backend/src/api/admin/client.ts
Normal file
@ -0,0 +1,191 @@
|
||||
import { Router, Request } from "express";
|
||||
import RequestError, { HttpStatusCode } from "../../helper/request_error";
|
||||
import promiseMiddleware from "../../helper/promiseMiddleware";
|
||||
import Client from "../../models/client";
|
||||
import verify, { Types } from "../middlewares/verify";
|
||||
import { randomBytes } from "crypto";
|
||||
|
||||
const ClientRouter: Router = Router();
|
||||
ClientRouter.route("/")
|
||||
/**
|
||||
* @api {get} /admin/client
|
||||
* @apiName AdminGetClients
|
||||
*
|
||||
* @apiGroup admin_client
|
||||
* @apiPermission admin
|
||||
*
|
||||
* @apiSuccess {Object[]} clients
|
||||
* @apiSuccess {String} clients._id The internally used id
|
||||
* @apiSuccess {String} clients.maintainer
|
||||
* @apiSuccess {Boolean} clients.internal
|
||||
* @apiSuccess {String} clients.name
|
||||
* @apiSuccess {String} clients.redirect_url
|
||||
* @apiSuccess {String} clients.website
|
||||
* @apiSuccess {String} clients.logo
|
||||
* @apiSuccess {String} clients.client_id Client ID used outside of DB
|
||||
* @apiSuccess {String} clients.client_secret
|
||||
*/
|
||||
.get(
|
||||
promiseMiddleware(async (req, res) => {
|
||||
let clients = await Client.find({});
|
||||
//ToDo check if user is required!
|
||||
res.json(clients);
|
||||
})
|
||||
)
|
||||
/**
|
||||
* @api {get} /admin/client
|
||||
* @apiName AdminAddClients
|
||||
*
|
||||
* @apiGroup admin_client
|
||||
* @apiPermission admin
|
||||
*
|
||||
* @apiParam {Boolean} internal Is it an internal app
|
||||
* @apiParam {String} name
|
||||
* @apiParam {String} redirect_url
|
||||
* @apiParam {String} website
|
||||
* @apiParam {String} logo
|
||||
*
|
||||
* @apiSuccess {Object[]} clients
|
||||
* @apiSuccess {String} clients._id The internally used id
|
||||
* @apiSuccess {String} clients.maintainer
|
||||
* @apiSuccess {Boolean} clients.internal
|
||||
* @apiSuccess {String} clients.name
|
||||
* @apiSuccess {String} clients.redirect_url
|
||||
* @apiSuccess {String} clients.website
|
||||
* @apiSuccess {String} clients.logo
|
||||
* @apiSuccess {String} clients.client_id Client ID used outside of DB
|
||||
* @apiSuccess {String} clients.client_secret
|
||||
*/
|
||||
.post(
|
||||
verify(
|
||||
{
|
||||
internal: {
|
||||
type: Types.BOOLEAN,
|
||||
optional: true,
|
||||
},
|
||||
name: {
|
||||
type: Types.STRING,
|
||||
},
|
||||
redirect_url: {
|
||||
type: Types.STRING,
|
||||
},
|
||||
website: {
|
||||
type: Types.STRING,
|
||||
},
|
||||
logo: {
|
||||
type: Types.STRING,
|
||||
optional: true,
|
||||
},
|
||||
featured: {
|
||||
type: Types.BOOLEAN,
|
||||
optional: true,
|
||||
},
|
||||
description: {
|
||||
type: Types.STRING,
|
||||
optional: true,
|
||||
},
|
||||
},
|
||||
true
|
||||
),
|
||||
promiseMiddleware(async (req, res) => {
|
||||
req.body.client_secret = randomBytes(32).toString("hex");
|
||||
let client = Client.new(req.body);
|
||||
client.maintainer = req.user._id;
|
||||
await Client.save(client);
|
||||
res.json(client);
|
||||
})
|
||||
);
|
||||
|
||||
ClientRouter.route("/:id")
|
||||
/**
|
||||
* @api {delete} /admin/client/:id
|
||||
* @apiParam {String} id Client _id
|
||||
* @apiName AdminDeleteClient
|
||||
*
|
||||
* @apiGroup admin_client
|
||||
* @apiPermission admin
|
||||
*
|
||||
* @apiSuccess {Boolean} success
|
||||
*/
|
||||
.delete(
|
||||
promiseMiddleware(async (req, res) => {
|
||||
let { id } = req.params;
|
||||
await Client.delete(id);
|
||||
res.json({ success: true });
|
||||
})
|
||||
)
|
||||
/**
|
||||
* @api {put} /admin/client/:id
|
||||
* @apiParam {String} id Client _id
|
||||
* @apiName AdminUpdateClient
|
||||
*
|
||||
* @apiGroup admin_client
|
||||
* @apiPermission admin
|
||||
*
|
||||
* @apiParam {Boolean} internal Is it an internal app
|
||||
* @apiParam {String} name
|
||||
* @apiParam {String} redirect_url
|
||||
* @apiParam {String} website
|
||||
* @apiParam {String} logo
|
||||
*
|
||||
* @apiSuccess {String} _id The internally used id
|
||||
* @apiSuccess {String} maintainer UserID of client maintainer
|
||||
* @apiSuccess {Boolean} internal Defines if it is a internal client
|
||||
* @apiSuccess {String} name The name of the Client
|
||||
* @apiSuccess {String} redirect_url Redirect URL after login
|
||||
* @apiSuccess {String} website Website of Client
|
||||
* @apiSuccess {String} logo The Logo of the Client (optional)
|
||||
* @apiSuccess {String} client_id Client ID used outside of DB
|
||||
* @apiSuccess {String} client_secret The client secret, that can be used to obtain token
|
||||
*/
|
||||
.put(
|
||||
verify(
|
||||
{
|
||||
internal: {
|
||||
type: Types.BOOLEAN,
|
||||
optional: true,
|
||||
},
|
||||
name: {
|
||||
type: Types.STRING,
|
||||
optional: true,
|
||||
},
|
||||
redirect_url: {
|
||||
type: Types.STRING,
|
||||
optional: true,
|
||||
},
|
||||
website: {
|
||||
type: Types.STRING,
|
||||
optional: true,
|
||||
},
|
||||
logo: {
|
||||
type: Types.STRING,
|
||||
optional: true,
|
||||
},
|
||||
featured: {
|
||||
type: Types.BOOLEAN,
|
||||
optional: true,
|
||||
},
|
||||
description: {
|
||||
type: Types.STRING,
|
||||
optional: true,
|
||||
},
|
||||
},
|
||||
true
|
||||
),
|
||||
promiseMiddleware(async (req, res) => {
|
||||
let { id } = req.query as { [key: string]: string };
|
||||
let client = await Client.findById(id);
|
||||
if (!client)
|
||||
throw new RequestError(
|
||||
req.__("Client not found"),
|
||||
HttpStatusCode.BAD_REQUEST
|
||||
);
|
||||
for (let key in req.body) {
|
||||
client[key] = req.body[key];
|
||||
}
|
||||
await Client.save(client);
|
||||
res.json(client);
|
||||
})
|
||||
);
|
||||
|
||||
export default ClientRouter;
|
24
Backend/src/api/admin/index.ts
Normal file
24
Backend/src/api/admin/index.ts
Normal file
@ -0,0 +1,24 @@
|
||||
import { Request, Router } from "express";
|
||||
import ClientRoute from "./client";
|
||||
import UserRoute from "./user";
|
||||
import RegCodeRoute from "./regcode";
|
||||
import PermissionRoute from "./permission";
|
||||
import { GetUserMiddleware } from "../middlewares/user";
|
||||
import RequestError, { HttpStatusCode } from "../../helper/request_error";
|
||||
|
||||
const AdminRoute: Router = Router();
|
||||
|
||||
AdminRoute.use(GetUserMiddleware(true, true), (req: Request, res, next) => {
|
||||
if (!req.isAdmin)
|
||||
throw new RequestError(
|
||||
"You have no permission to access this API",
|
||||
HttpStatusCode.FORBIDDEN
|
||||
);
|
||||
else next();
|
||||
});
|
||||
|
||||
AdminRoute.use("/client", ClientRoute);
|
||||
AdminRoute.use("/regcode", RegCodeRoute);
|
||||
AdminRoute.use("/user", UserRoute);
|
||||
AdminRoute.use("/permission", PermissionRoute);
|
||||
export default AdminRoute;
|
111
Backend/src/api/admin/permission.ts
Normal file
111
Backend/src/api/admin/permission.ts
Normal file
@ -0,0 +1,111 @@
|
||||
import { Request, Router } from "express";
|
||||
import { GetUserMiddleware } from "../middlewares/user";
|
||||
import RequestError, { HttpStatusCode } from "../../helper/request_error";
|
||||
import promiseMiddleware from "../../helper/promiseMiddleware";
|
||||
import Permission from "../../models/permissions";
|
||||
import verify, { Types } from "../middlewares/verify";
|
||||
import Client from "../../models/client";
|
||||
import { ObjectID } from "bson";
|
||||
|
||||
const PermissionRoute: Router = Router();
|
||||
PermissionRoute.route("/")
|
||||
/**
|
||||
* @api {get} /admin/permission
|
||||
* @apiName AdminGetPermissions
|
||||
*
|
||||
* @apiParam client Optionally filter by client _id
|
||||
*
|
||||
* @apiGroup admin_permission
|
||||
* @apiPermission admin
|
||||
*
|
||||
* @apiSuccess {Object[]} permissions
|
||||
* @apiSuccess {String} permissions._id The ID
|
||||
* @apiSuccess {String} permissions.name Permission name
|
||||
* @apiSuccess {String} permissions.description A description, that makes it clear to the user, what this Permission allows to do
|
||||
* @apiSuccess {String} permissions.client The ID of the owning client
|
||||
*/
|
||||
.get(
|
||||
promiseMiddleware(async (req, res) => {
|
||||
let query = {};
|
||||
if (req.query.client) {
|
||||
query = { client: new ObjectID(req.query.client as string) };
|
||||
}
|
||||
let permissions = await Permission.find(query);
|
||||
res.json(permissions);
|
||||
})
|
||||
)
|
||||
/**
|
||||
* @api {post} /admin/permission
|
||||
* @apiName AdminAddPermission
|
||||
*
|
||||
* @apiParam client The ID of the owning client
|
||||
* @apiParam name Permission name
|
||||
* @apiParam description A description, that makes it clear to the user, what this Permission allows to do
|
||||
*
|
||||
* @apiGroup admin_permission
|
||||
* @apiPermission admin
|
||||
*
|
||||
* @apiSuccess {Object[]} permissions
|
||||
* @apiSuccess {String} permissions._id The ID
|
||||
* @apiSuccess {String} permissions.name Permission name
|
||||
* @apiSuccess {String} permissions.description A description, that makes it clear to the user, what this Permission allows to do
|
||||
* @apiSuccess {String} permissions.client The ID of the owning client
|
||||
* @apiSuccess {String} permissions.grant_type The type of the permission. "user" | "client" granted
|
||||
*/
|
||||
.post(
|
||||
verify(
|
||||
{
|
||||
client: {
|
||||
type: Types.STRING,
|
||||
},
|
||||
name: {
|
||||
type: Types.STRING,
|
||||
},
|
||||
description: {
|
||||
type: Types.STRING,
|
||||
},
|
||||
type: {
|
||||
type: Types.ENUM,
|
||||
values: ["user", "client"],
|
||||
},
|
||||
},
|
||||
true
|
||||
),
|
||||
promiseMiddleware(async (req, res) => {
|
||||
let client = await Client.findById(req.body.client);
|
||||
if (!client) {
|
||||
throw new RequestError(
|
||||
"Client not found",
|
||||
HttpStatusCode.BAD_REQUEST
|
||||
);
|
||||
}
|
||||
let permission = Permission.new({
|
||||
description: req.body.description,
|
||||
name: req.body.name,
|
||||
client: client._id,
|
||||
grant_type: req.body.type,
|
||||
});
|
||||
await Permission.save(permission);
|
||||
res.json(permission);
|
||||
})
|
||||
)
|
||||
/**
|
||||
* @api {delete} /admin/permission
|
||||
* @apiName AdminDeletePermission
|
||||
*
|
||||
* @apiParam id The permission ID
|
||||
*
|
||||
* @apiGroup admin_permission
|
||||
* @apiPermission admin
|
||||
*
|
||||
* @apiSuccess {Boolean} success
|
||||
*/
|
||||
.delete(
|
||||
promiseMiddleware(async (req, res) => {
|
||||
let { id } = req.query as { [key: string]: string };
|
||||
await Permission.delete(id);
|
||||
res.json({ success: true });
|
||||
})
|
||||
);
|
||||
|
||||
export default PermissionRoute;
|
69
Backend/src/api/admin/regcode.ts
Normal file
69
Backend/src/api/admin/regcode.ts
Normal file
@ -0,0 +1,69 @@
|
||||
import { Request, Router } from "express";
|
||||
import promiseMiddleware from "../../helper/promiseMiddleware";
|
||||
import RegCode from "../../models/regcodes";
|
||||
import { randomBytes } from "crypto";
|
||||
import moment = require("moment");
|
||||
import { GetUserMiddleware } from "../middlewares/user";
|
||||
import { HttpStatusCode } from "../../helper/request_error";
|
||||
|
||||
const RegCodeRoute: Router = Router();
|
||||
RegCodeRoute.route("/")
|
||||
/**
|
||||
* @api {get} /admin/regcode
|
||||
* @apiName AdminGetRegcodes
|
||||
*
|
||||
* @apiGroup admin_regcode
|
||||
* @apiPermission admin
|
||||
*
|
||||
* @apiSuccess {Object[]} regcodes
|
||||
* @apiSuccess {String} permissions._id The ID
|
||||
* @apiSuccess {String} permissions.token The Regcode Token
|
||||
* @apiSuccess {String} permissions.valid Defines if the Regcode is valid
|
||||
* @apiSuccess {String} permissions.validTill Expiration date of RegCode
|
||||
*/
|
||||
.get(
|
||||
promiseMiddleware(async (req, res) => {
|
||||
let regcodes = await RegCode.find({});
|
||||
res.json(regcodes);
|
||||
})
|
||||
)
|
||||
/**
|
||||
* @api {delete} /admin/regcode
|
||||
* @apiName AdminDeleteRegcode
|
||||
*
|
||||
* @apiParam {String} id The id of the RegCode
|
||||
*
|
||||
* @apiGroup admin_regcode
|
||||
* @apiPermission admin
|
||||
*
|
||||
* @apiSuccess {Boolean} success
|
||||
*/
|
||||
.delete(
|
||||
promiseMiddleware(async (req, res) => {
|
||||
let { id } = req.query as { [key: string]: string };
|
||||
await RegCode.delete(id);
|
||||
res.json({ success: true });
|
||||
})
|
||||
)
|
||||
/**
|
||||
* @api {post} /admin/regcode
|
||||
* @apiName AdminAddRegcode
|
||||
*
|
||||
* @apiGroup admin_regcode
|
||||
* @apiPermission admin
|
||||
*
|
||||
* @apiSuccess {String} code The newly created code
|
||||
*/
|
||||
.post(
|
||||
promiseMiddleware(async (req, res) => {
|
||||
let regcode = RegCode.new({
|
||||
token: randomBytes(10).toString("hex"),
|
||||
valid: true,
|
||||
validTill: moment().add("1", "month").toDate(),
|
||||
});
|
||||
await RegCode.save(regcode);
|
||||
res.json({ code: regcode.token });
|
||||
})
|
||||
);
|
||||
|
||||
export default RegCodeRoute;
|
93
Backend/src/api/admin/user.ts
Normal file
93
Backend/src/api/admin/user.ts
Normal file
@ -0,0 +1,93 @@
|
||||
import { Request, Router } from "express";
|
||||
import { GetUserMiddleware } from "../middlewares/user";
|
||||
import { HttpStatusCode } from "../../helper/request_error";
|
||||
import promiseMiddleware from "../../helper/promiseMiddleware";
|
||||
import User from "../../models/user";
|
||||
import Mail from "../../models/mail";
|
||||
import RefreshToken from "../../models/refresh_token";
|
||||
import LoginToken from "../../models/login_token";
|
||||
|
||||
const UserRoute: Router = Router();
|
||||
UserRoute.use(GetUserMiddleware(true, true), (req: Request, res, next) => {
|
||||
if (!req.isAdmin) res.sendStatus(HttpStatusCode.FORBIDDEN);
|
||||
else next();
|
||||
});
|
||||
|
||||
UserRoute.route("/")
|
||||
/**
|
||||
* @api {get} /admin/user
|
||||
* @apiName AdminGetUsers
|
||||
*
|
||||
* @apiGroup admin_user
|
||||
* @apiPermission admin
|
||||
* @apiSuccess {Object[]} user
|
||||
* @apiSuccess {String} user._id The internal id of the user
|
||||
* @apiSuccess {String} user.uid The public UID of the user
|
||||
* @apiSuccess {String} user.username The username
|
||||
* @apiSuccess {String} user.name The real name
|
||||
* @apiSuccess {Date} user.birthday The birthday
|
||||
* @apiSuccess {Number} user.gender 0 = none, 1 = male, 2 = female, 3 = other
|
||||
* @apiSuccess {Boolean} user.admin Is admin or not
|
||||
*/
|
||||
.get(
|
||||
promiseMiddleware(async (req, res) => {
|
||||
let users = await User.find({});
|
||||
users.forEach(
|
||||
(e) => delete e.password && delete e.salt && delete e.encryption_key
|
||||
);
|
||||
res.json(users);
|
||||
})
|
||||
)
|
||||
/**
|
||||
* @api {delete} /admin/user
|
||||
* @apiName AdminDeleteUser
|
||||
*
|
||||
* @apiParam {String} id The User ID
|
||||
*
|
||||
* @apiGroup admin_user
|
||||
* @apiPermission admin
|
||||
*
|
||||
* @apiSuccess {Boolean} success
|
||||
*/
|
||||
.delete(
|
||||
promiseMiddleware(async (req, res) => {
|
||||
let { id } = req.query as { [key: string]: string };
|
||||
let user = await User.findById(id);
|
||||
|
||||
await Promise.all([
|
||||
user.mails.map((mail) => Mail.delete(mail)),
|
||||
[
|
||||
RefreshToken.deleteFilter({ user: user._id }),
|
||||
LoginToken.deleteFilter({ user: user._id }),
|
||||
],
|
||||
]);
|
||||
|
||||
await User.delete(user);
|
||||
res.json({ success: true });
|
||||
})
|
||||
)
|
||||
/**
|
||||
* @api {put} /admin/user
|
||||
* @apiName AdminChangeUser
|
||||
*
|
||||
* @apiParam {String} id The User ID
|
||||
*
|
||||
* @apiGroup admin_user
|
||||
* @apiPermission admin
|
||||
*
|
||||
* @apiSuccess {Boolean} success
|
||||
*
|
||||
* @apiDescription Flipps the user role:
|
||||
* admin -> user
|
||||
* user -> admin
|
||||
*/
|
||||
.put(
|
||||
promiseMiddleware(async (req, res) => {
|
||||
let { id } = req.query as { [key: string]: string };
|
||||
let user = await User.findById(id);
|
||||
user.admin = !user.admin;
|
||||
await User.save(user);
|
||||
res.json({ success: true });
|
||||
})
|
||||
);
|
||||
export default UserRoute;
|
Reference in New Issue
Block a user