Add JRPC API, reworked Login and User pages
This commit is contained in:
@ -1,106 +1,70 @@
|
||||
import { NextFunction, Request, Response } from "express";
|
||||
import LoginToken, { CheckToken } from "../../models/login_token";
|
||||
import Logging from "@hibas123/nodelogging";
|
||||
import RequestError, { HttpStatusCode } from "../../helper/request_error";
|
||||
import User from "../../models/user";
|
||||
import promiseMiddleware from "../../helper/promiseMiddleware";
|
||||
|
||||
class Invalid extends Error {}
|
||||
|
||||
/**
|
||||
* Returns customized Middleware function, that could also be called directly
|
||||
* by code and will return true or false depending on the token. In the false
|
||||
* case it will also send error and redirect if json is not set
|
||||
* @param json Default false. Checks if requests wants an json or html for returning errors
|
||||
* @param special_required Default false. If true, a special token is required
|
||||
* @param redirect_uri Default current uri. Sets the uri to redirect, if json is not set and user not logged in
|
||||
* @param validated Default true. If false, the token must not be validated
|
||||
*/
|
||||
export function GetUserMiddleware(
|
||||
json = false,
|
||||
special_required: boolean = false,
|
||||
redirect_uri?: string,
|
||||
validated = true
|
||||
) {
|
||||
return promiseMiddleware(async function (
|
||||
req: Request,
|
||||
res: Response,
|
||||
next?: NextFunction
|
||||
) {
|
||||
const invalid = (message: string) => {
|
||||
throw new Invalid(req.__(message));
|
||||
};
|
||||
try {
|
||||
let { login, special } = req.query as { [key: string]: string };
|
||||
if (!login) {
|
||||
login = req.cookies.login;
|
||||
special = req.cookies.special;
|
||||
}
|
||||
if (!login) invalid("No login token");
|
||||
if (!special && special_required) invalid("No special token");
|
||||
|
||||
let token = await LoginToken.findOne({ token: login, valid: true });
|
||||
if (!(await CheckToken(token, validated)))
|
||||
invalid("Login token invalid");
|
||||
|
||||
let user = await User.findById(token.user);
|
||||
if (!user) {
|
||||
token.valid = false;
|
||||
await LoginToken.save(token);
|
||||
invalid("Login token invalid");
|
||||
}
|
||||
|
||||
let special_token;
|
||||
if (special) {
|
||||
Logging.debug("Special found");
|
||||
special_token = await LoginToken.findOne({
|
||||
token: special,
|
||||
special: true,
|
||||
valid: true,
|
||||
user: token.user,
|
||||
});
|
||||
if (!(await CheckToken(special_token, validated)))
|
||||
invalid("Special token invalid");
|
||||
req.special = true;
|
||||
}
|
||||
|
||||
req.user = user;
|
||||
req.isAdmin = user.admin;
|
||||
req.token = {
|
||||
login: token,
|
||||
special: special_token,
|
||||
};
|
||||
|
||||
if (next) next();
|
||||
return true;
|
||||
} catch (e) {
|
||||
if (e instanceof Invalid) {
|
||||
if (req.method === "GET" && !json) {
|
||||
res.status(HttpStatusCode.UNAUTHORIZED);
|
||||
res.redirect(
|
||||
"/login?base64=true&state=" +
|
||||
Buffer.from(
|
||||
redirect_uri ? redirect_uri : req.originalUrl
|
||||
).toString("base64")
|
||||
);
|
||||
} else {
|
||||
throw new RequestError(
|
||||
req.__(
|
||||
"You are not logged in or your login is expired" +
|
||||
` (${e.message})`
|
||||
),
|
||||
HttpStatusCode.UNAUTHORIZED,
|
||||
undefined,
|
||||
{ auth: true }
|
||||
);
|
||||
}
|
||||
} else {
|
||||
if (next) next(e);
|
||||
else throw e;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export const UserMiddleware = GetUserMiddleware();
|
||||
import { NextFunction, Request, Response } from "express";
|
||||
import Logging from "@hibas123/nodelogging";
|
||||
import RequestError, { HttpStatusCode } from "../../helper/request_error";
|
||||
import promiseMiddleware from "../../helper/promiseMiddleware";
|
||||
import { requireLoginState } from "../../helper/login";
|
||||
|
||||
class Invalid extends Error { }
|
||||
|
||||
/**
|
||||
* Returns customized Middleware function, that could also be called directly
|
||||
* by code and will return true or false depending on the token. In the false
|
||||
* case it will also send error and redirect if json is not set
|
||||
* @param json Default false. Checks if requests wants an json or html for returning errors
|
||||
* @param special_required Default false. If true, a special token is required
|
||||
* @param redirect_uri Default current uri. Sets the uri to redirect, if json is not set and user not logged in
|
||||
* @param validated Default true. If false, the token must not be validated
|
||||
*/
|
||||
export function GetUserMiddleware(
|
||||
json = false,
|
||||
special_required: boolean = false,
|
||||
redirect_uri?: string,
|
||||
validated = true
|
||||
) {
|
||||
return promiseMiddleware(async function (
|
||||
req: Request,
|
||||
res: Response,
|
||||
next?: NextFunction
|
||||
) {
|
||||
const invalid = (message: string) => {
|
||||
throw new Invalid(req.__(message));
|
||||
};
|
||||
try {
|
||||
if (!requireLoginState(req, validated, special_required)) {
|
||||
invalid("Not logged in");
|
||||
}
|
||||
|
||||
if (next) next();
|
||||
return true;
|
||||
} catch (e) {
|
||||
Logging.getChild("UserMiddleware").warn(e);
|
||||
if (e instanceof Invalid) {
|
||||
if (req.method === "GET" && !json) {
|
||||
res.status(HttpStatusCode.UNAUTHORIZED);
|
||||
res.redirect(
|
||||
"/login?base64=true&state=" +
|
||||
Buffer.from(
|
||||
redirect_uri ? redirect_uri : req.originalUrl
|
||||
).toString("base64")
|
||||
);
|
||||
} else {
|
||||
throw new RequestError(
|
||||
req.__(
|
||||
"You are not logged in or your login is expired" +
|
||||
` (${e.message})`
|
||||
),
|
||||
HttpStatusCode.UNAUTHORIZED,
|
||||
undefined,
|
||||
{ auth: true }
|
||||
);
|
||||
}
|
||||
} else {
|
||||
if (next) next(e);
|
||||
else throw e;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export const UserMiddleware = GetUserMiddleware();
|
||||
|
Reference in New Issue
Block a user