Add new profile endpoint

Add some logging output for auth failures
This commit is contained in:
Fabian Stamm 2023-04-07 22:51:08 +02:00
parent 0453e461c9
commit e27be1374b
9 changed files with 63 additions and 18 deletions

View File

@ -1,6 +1,5 @@
{
"name": "@hibas123/openauth-backend",
"version": "1.1.2",
"main": "lib/index.js",
"author": "Fabian Stamm <dev@fabianstamm.de>",
"license": "MIT",

View File

@ -5,6 +5,7 @@ import { validateJWT } from "../../keys";
import User from "../../models/user";
import Mail from "../../models/mail";
import { OAuthJWT } from "../../helper/jwt";
import Logging from "@hibas123/nodelogging";
export function GetClientAuthMiddleware(
checksecret = true,
@ -67,13 +68,16 @@ export function GetClientApiAuthMiddleware(permissions?: string[]) {
return async (req: Request, res: Response, next: NextFunction) => {
try {
const invalid_err = new RequestError(
req.__("You are not logged in or your login is expired"),
req.__("Unauthorized"),
HttpStatusCode.UNAUTHORIZED
);
let token =
(req.query.access_token as string) ||
(req.headers.authorization as string);
if (!token) throw invalid_err;
if (!token) {
Logging.debug("No token found. Searched in query (access_token) and header (authorization)");
throw invalid_err;
}
if (token.toLowerCase().startsWith("bearer "))
token = token.substring(7);
@ -82,22 +86,31 @@ export function GetClientApiAuthMiddleware(permissions?: string[]) {
try {
data = await validateJWT(token);
} catch (err) {
Logging.debug("Invalid JWT", err.message);
throw invalid_err;
}
let user = await User.findOne({ uid: data.user });
if (!user) throw invalid_err;
if (!user) {
Logging.debug("User not found");
throw invalid_err;
}
let client = await Client.findOne({ client_id: data.application });
if (!client) throw invalid_err;
if (!client) {
Logging.debug("Client not found");
throw invalid_err;
}
if (
permissions &&
(!data.permissions ||
!permissions.every((e) => data.permissions.indexOf(e) >= 0))
)
) {
Logging.debug("Invalid permissions");
throw invalid_err;
}
req.user = user;
req.client = client;

View File

@ -3,8 +3,9 @@ import GetAuthRoute from "./auth";
import JWTRoute from "./jwt";
import Public from "./public";
import RefreshTokenRoute from "./refresh";
import ProfileRoute from "./profile";
const OAuthRoue: Router = Router();
const OAuthRoute: Router = Router();
/**
* @api {post} /oauth/auth
* @apiName OAuthAuth
@ -19,7 +20,7 @@ const OAuthRoue: Router = Router();
* @apiParam {String} state State, that will be passed to redirect_uri for client
* @apiParam {String} nored Deactivates the Redirect response from server and instead returns the redirect URI in JSON response
*/
OAuthRoue.post("/auth", GetAuthRoute(false));
OAuthRoute.post("/auth", GetAuthRoute(false));
/**
* @api {get} /oauth/jwt
@ -32,7 +33,7 @@ OAuthRoue.post("/auth", GetAuthRoute(false));
*
* @apiSuccess {String} token The JWT that allowes the application to access the recources granted for refresh token
*/
OAuthRoue.get("/jwt", JWTRoute);
OAuthRoute.get("/jwt", JWTRoute);
/**
* @api {get} /oauth/public
@ -43,7 +44,7 @@ OAuthRoue.get("/jwt", JWTRoute);
*
* @apiSuccess {String} public_key The applications public_key. Used to verify JWT.
*/
OAuthRoue.get("/public", Public);
OAuthRoute.get("/public", Public);
/**
* @api {get} /oauth/refresh
@ -51,7 +52,7 @@ OAuthRoue.get("/public", Public);
*
* @apiGroup oauth
*/
OAuthRoue.get("/refresh", RefreshTokenRoute);
OAuthRoute.get("/refresh", RefreshTokenRoute);
/**
* @api {post} /oauth/refresh
@ -59,5 +60,14 @@ OAuthRoue.get("/refresh", RefreshTokenRoute);
*
* @apiGroup oauth
*/
OAuthRoue.post("/refresh", RefreshTokenRoute);
export default OAuthRoue;
OAuthRoute.post("/refresh", RefreshTokenRoute);
/**
* @api {get} /oauth/profile
* @apiName OAuthProfile
*
* @apiGroup oauth
*/
OAuthRoute.get("/profile", ProfileRoute);
export default OAuthRoute;

View File

@ -0,0 +1,23 @@
import Mail from "../../models/mail";
import { GetClientApiAuthMiddleware } from "../middlewares/client";
import Stacker from "../middlewares/stacker";
import { Request, Response } from "express";
export default Stacker(GetClientApiAuthMiddleware(), async (req: Request, res) => {
let mails = await Promise.all(
req.user.mails.map((id) => Mail.findById(id))
);
let mail = mails.find((e) => e.primary) || mails[0];
res.json({
user_id: req.user.uid,
id: req.user.uid,
ID: req.user.uid,
sub: req.user.uid,
email: mail.mail,
username: req.user.username,
displayName: req.user.name,
displayNameClaim: req.user.name,
});
})

View File

@ -101,7 +101,7 @@ export default async function TestData() {
data: "IIRW2P2UJRDDO2LDIRYW4LSREZLWMOKDNBJES2LLHRREK3R6KZJQ",
expires: null,
});
TwoFactor.save(t);
await TwoFactor.save(t);
}
let login_token = await LoginToken.findOne({ token: "test01" });

View File

@ -63,8 +63,7 @@ export default class Web {
let m = req.method;
while (m.length < 4) m += " ";
Logging.log(
`${m} ${req.originalUrl} ${
(req as any).language || ""
`${m} ${req.originalUrl} ${(req as any).language || ""
} ${resColor}${res.statusCode}\x1b[0m - ${time}ms`
);
res.removeListener("finish", listener);
@ -107,7 +106,7 @@ export default class Web {
if (error.status === 500 && !(<any>error).nolog) {
Logging.error(error);
} else {
Logging.log("Responded with Error", error.status);
Logging.log("Responded with Error", error.status, error.message);
}
if (req.accepts(["json"])) {

1
Frontend Submodule

@ -0,0 +1 @@
Subproject commit 8ed18a9695b38418b118c1b60845b001b2bca8d3

View File

@ -1,6 +1,5 @@
{
"name": "@hibas123/openauth-views-v1",
"version": "1.0.0",
"main": "index.js",
"author": "Fabian Stamm <dev@fabianstamm.de>",
"license": "MIT",

View File

@ -1,5 +1,6 @@
{
"name": "@hibas123/openauth",
"version": "1.2.0",
"author": "Fabian Stamm <dev@fabianstamm.de>",
"private": true,
"scripts": {