From e27be1374bad8bb19e0d1205d47212e2bb741bbd Mon Sep 17 00:00:00 2001 From: Fabian Stamm Date: Fri, 7 Apr 2023 22:51:08 +0200 Subject: [PATCH] Add new profile endpoint Add some logging output for auth failures --- Backend/package.json | 1 - Backend/src/api/middlewares/client.ts | 23 ++++++++++++++++++----- Backend/src/api/oauth/index.ts | 24 +++++++++++++++++------- Backend/src/api/oauth/profile.ts | 23 +++++++++++++++++++++++ Backend/src/testdata.ts | 2 +- Backend/src/web.ts | 5 ++--- Frontend | 1 + FrontendLegacy/package.json | 1 - package.json | 1 + 9 files changed, 63 insertions(+), 18 deletions(-) create mode 100644 Backend/src/api/oauth/profile.ts create mode 160000 Frontend diff --git a/Backend/package.json b/Backend/package.json index 66562ea..4774d78 100644 --- a/Backend/package.json +++ b/Backend/package.json @@ -1,6 +1,5 @@ { "name": "@hibas123/openauth-backend", - "version": "1.1.2", "main": "lib/index.js", "author": "Fabian Stamm ", "license": "MIT", diff --git a/Backend/src/api/middlewares/client.ts b/Backend/src/api/middlewares/client.ts index c6f44a7..59353e5 100644 --- a/Backend/src/api/middlewares/client.ts +++ b/Backend/src/api/middlewares/client.ts @@ -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; diff --git a/Backend/src/api/oauth/index.ts b/Backend/src/api/oauth/index.ts index a68bad6..562f88a 100644 --- a/Backend/src/api/oauth/index.ts +++ b/Backend/src/api/oauth/index.ts @@ -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; diff --git a/Backend/src/api/oauth/profile.ts b/Backend/src/api/oauth/profile.ts new file mode 100644 index 0000000..3e0ea36 --- /dev/null +++ b/Backend/src/api/oauth/profile.ts @@ -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, + }); +}) diff --git a/Backend/src/testdata.ts b/Backend/src/testdata.ts index 957476e..2744316 100644 --- a/Backend/src/testdata.ts +++ b/Backend/src/testdata.ts @@ -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" }); diff --git a/Backend/src/web.ts b/Backend/src/web.ts index aba2f00..2b636f7 100644 --- a/Backend/src/web.ts +++ b/Backend/src/web.ts @@ -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 && !(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"])) { diff --git a/Frontend b/Frontend new file mode 160000 index 0000000..8ed18a9 --- /dev/null +++ b/Frontend @@ -0,0 +1 @@ +Subproject commit 8ed18a9695b38418b118c1b60845b001b2bca8d3 diff --git a/FrontendLegacy/package.json b/FrontendLegacy/package.json index 4b692e1..3c7c004 100644 --- a/FrontendLegacy/package.json +++ b/FrontendLegacy/package.json @@ -1,6 +1,5 @@ { "name": "@hibas123/openauth-views-v1", - "version": "1.0.0", "main": "index.js", "author": "Fabian Stamm ", "license": "MIT", diff --git a/package.json b/package.json index 75728d4..3c404d6 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,6 @@ { "name": "@hibas123/openauth", + "version": "1.2.0", "author": "Fabian Stamm ", "private": true, "scripts": {