Implementing basic auth_grant
This commit is contained in:
		
							
								
								
									
										19
									
								
								.vscode/launch.json
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										19
									
								
								.vscode/launch.json
									
									
									
									
										vendored
									
									
								
							@ -3,13 +3,14 @@
 | 
				
			|||||||
   // Hover to view descriptions of existing attributes.
 | 
					   // Hover to view descriptions of existing attributes.
 | 
				
			||||||
   // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
 | 
					   // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
 | 
				
			||||||
   "version": "0.2.0",
 | 
					   "version": "0.2.0",
 | 
				
			||||||
   "configurations": [{
 | 
					   "configurations": [
 | 
				
			||||||
      "type": "node",
 | 
					      {
 | 
				
			||||||
      "request": "launch",
 | 
					         "type": "node",
 | 
				
			||||||
      "name": "Launch Program",
 | 
					         "request": "launch",
 | 
				
			||||||
      "program": "${workspaceFolder}/lib/index.js",
 | 
					         "name": "Launch Program",
 | 
				
			||||||
      "outFiles": [
 | 
					         "program": "${workspaceFolder}/lib/index.js",
 | 
				
			||||||
         "${workspaceFolder}/**/*.js"
 | 
					         "outFiles": ["${workspaceFolder}/**/*.js"],
 | 
				
			||||||
      ]
 | 
					         "preLaunchTask": "build"
 | 
				
			||||||
   }]
 | 
					      }
 | 
				
			||||||
 | 
					   ]
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
							
								
								
									
										22
									
								
								.vscode/tasks.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								.vscode/tasks.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,22 @@
 | 
				
			|||||||
 | 
					{
 | 
				
			||||||
 | 
					   // Unter https://go.microsoft.com/fwlink/?LinkId=733558
 | 
				
			||||||
 | 
					   // finden Sie Informationen zum Format von "tasks.json"
 | 
				
			||||||
 | 
					   "version": "2.0.0",
 | 
				
			||||||
 | 
					   "tasks": [
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					         "type": "npm",
 | 
				
			||||||
 | 
					         "script": "build-ts",
 | 
				
			||||||
 | 
					         "group": "build",
 | 
				
			||||||
 | 
					         "problemMatcher": ["$tsc"],
 | 
				
			||||||
 | 
					         "presentation": {
 | 
				
			||||||
 | 
					            "echo": true,
 | 
				
			||||||
 | 
					            "reveal": "never",
 | 
				
			||||||
 | 
					            "focus": false,
 | 
				
			||||||
 | 
					            "panel": "shared",
 | 
				
			||||||
 | 
					            "showReuseMessage": true,
 | 
				
			||||||
 | 
					            "clear": false
 | 
				
			||||||
 | 
					         },
 | 
				
			||||||
 | 
					         "label": "build"
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					   ]
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -9,5 +9,7 @@
 | 
				
			|||||||
	"No special token": "No special token",
 | 
						"No special token": "No special token",
 | 
				
			||||||
	"You are not logged in or your login is expired(No special token)": "You are not logged in or your login is expired(No special token)",
 | 
						"You are not logged in or your login is expired(No special token)": "You are not logged in or your login is expired(No special token)",
 | 
				
			||||||
	"Special token invalid": "Special token invalid",
 | 
						"Special token invalid": "Special token invalid",
 | 
				
			||||||
	"You are not logged in or your login is expired(Special token invalid)": "You are not logged in or your login is expired(Special token invalid)"
 | 
						"You are not logged in or your login is expired(Special token invalid)": "You are not logged in or your login is expired(Special token invalid)",
 | 
				
			||||||
 | 
						"No login token": "No login token",
 | 
				
			||||||
 | 
						"Login token invalid": "Login token invalid"
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -9,6 +9,7 @@
 | 
				
			|||||||
      "install": "run-s install-views install-views_repo",
 | 
					      "install": "run-s install-views install-views_repo",
 | 
				
			||||||
      "build": "run-s build-ts build-doc build-views build-views_repo",
 | 
					      "build": "run-s build-ts build-doc build-views build-views_repo",
 | 
				
			||||||
      "watch": "concurrently \"npm:watch-*\"",
 | 
					      "watch": "concurrently \"npm:watch-*\"",
 | 
				
			||||||
 | 
					      "dev": "npm run watch",
 | 
				
			||||||
      "build-doc": "apidoc -i src/ -p apidoc/",
 | 
					      "build-doc": "apidoc -i src/ -p apidoc/",
 | 
				
			||||||
      "build-ts": "tsc",
 | 
					      "build-ts": "tsc",
 | 
				
			||||||
      "watch-ts": "tsc -w",
 | 
					      "watch-ts": "tsc -w",
 | 
				
			||||||
 | 
				
			|||||||
@ -1,6 +1,6 @@
 | 
				
			|||||||
import { Request, Response, Router } from "express"
 | 
					import { Request, Response, Router } from "express"
 | 
				
			||||||
import Stacker from "../middlewares/stacker";
 | 
					import Stacker from "../middlewares/stacker";
 | 
				
			||||||
import { GetClientAuthMiddleware } from "../middlewares/client";
 | 
					import { GetClientAuthMiddleware, GetClientApiAuthMiddleware } from "../middlewares/client";
 | 
				
			||||||
import { GetUserMiddleware } from "../middlewares/user";
 | 
					import { GetUserMiddleware } from "../middlewares/user";
 | 
				
			||||||
import { createJWT } from "../../keys";
 | 
					import { createJWT } from "../../keys";
 | 
				
			||||||
import Client from "../../models/client";
 | 
					import Client from "../../models/client";
 | 
				
			||||||
@ -44,4 +44,13 @@ ClientRouter.get("/user", Stacker(GetClientAuthMiddleware(false), GetUserMiddlew
 | 
				
			|||||||
   res.redirect(redirect_uri + "?jwt=" + jwt + (state ? `&state=${state}` : ""));
 | 
					   res.redirect(redirect_uri + "?jwt=" + jwt + (state ? `&state=${state}` : ""));
 | 
				
			||||||
}));
 | 
					}));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ClientRouter.get("/account", Stacker(GetClientApiAuthMiddleware(), async (req: Request, res) => {
 | 
				
			||||||
 | 
					   res.json({
 | 
				
			||||||
 | 
					      user: {
 | 
				
			||||||
 | 
					         username: req.user.username,
 | 
				
			||||||
 | 
					         name: req.user.name,
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					   })
 | 
				
			||||||
 | 
					}));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default ClientRouter;
 | 
					export default ClientRouter;
 | 
				
			||||||
@ -7,38 +7,103 @@ import Permission, { IPermission } from "../../models/permissions";
 | 
				
			|||||||
import ClientCode from "../../models/client_code";
 | 
					import ClientCode from "../../models/client_code";
 | 
				
			||||||
import moment = require("moment");
 | 
					import moment = require("moment");
 | 
				
			||||||
import { randomBytes } from "crypto";
 | 
					import { randomBytes } from "crypto";
 | 
				
			||||||
import { ObjectID } from "bson";
 | 
					// import { ObjectID } from "bson";
 | 
				
			||||||
 | 
					import Grant, { IGrant } from "../../models/grants";
 | 
				
			||||||
 | 
					import GetAuthPage from "../../views/authorize";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const AuthRoute = Stacker(GetUserMiddleware(true), async (req: Request, res: Response) => {
 | 
					// const AuthRoute = Stacker(GetUserMiddleware(true), async (req: Request, res: Response) => {
 | 
				
			||||||
 | 
					//    let { response_type, client_id, redirect_uri, scope, state, nored } = req.query;
 | 
				
			||||||
 | 
					//    const sendError = (type) => {
 | 
				
			||||||
 | 
					//       if (redirect_uri === "$local")
 | 
				
			||||||
 | 
					//          redirect_uri = "/code";
 | 
				
			||||||
 | 
					//       res.redirect(redirect_uri += `?error=${type}&state=${state}`);
 | 
				
			||||||
 | 
					//    }
 | 
				
			||||||
 | 
					//    /**
 | 
				
			||||||
 | 
					//     * error
 | 
				
			||||||
 | 
					//          REQUIRED.  A single ASCII [USASCII] error code from the
 | 
				
			||||||
 | 
					//          following:
 | 
				
			||||||
 | 
					//          invalid_request
 | 
				
			||||||
 | 
					//                The request is missing a required parameter, includes an
 | 
				
			||||||
 | 
					//                invalid parameter value, includes a parameter more than
 | 
				
			||||||
 | 
					//                once, or is otherwise malformed.
 | 
				
			||||||
 | 
					//          unauthorized_client
 | 
				
			||||||
 | 
					//                The client is not authorized to request an authorization
 | 
				
			||||||
 | 
					//                code using this method.
 | 
				
			||||||
 | 
					//          access_denied
 | 
				
			||||||
 | 
					//                The resource owner or authorization server denied the
 | 
				
			||||||
 | 
					//                request.
 | 
				
			||||||
 | 
					//     */
 | 
				
			||||||
 | 
					//    try {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//       if (response_type !== "code") {
 | 
				
			||||||
 | 
					//          return sendError("unsupported_response_type");
 | 
				
			||||||
 | 
					//       } else {
 | 
				
			||||||
 | 
					//          let client = await Client.findOne({ client_id: client_id })
 | 
				
			||||||
 | 
					//          if (!client) {
 | 
				
			||||||
 | 
					//             return sendError("unauthorized_client")
 | 
				
			||||||
 | 
					//          }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//          if (redirect_uri && client.redirect_url !== redirect_uri) {
 | 
				
			||||||
 | 
					//             Logging.log(redirect_uri, client.redirect_url);
 | 
				
			||||||
 | 
					//             return res.send("Invalid redirect_uri. Please check the integrity of the site requesting and contact the administrator of the page, you want to authorize!");
 | 
				
			||||||
 | 
					//          }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//          let permissions: IPermission[] = [];
 | 
				
			||||||
 | 
					//          if (scope) {
 | 
				
			||||||
 | 
					//             let perms = (<string>scope).split(";").filter(e => e !== "read_user").map(p => new ObjectID(p));
 | 
				
			||||||
 | 
					//             permissions = await Permission.find({ _id: { $in: perms } })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//             if (permissions.length != perms.length) {
 | 
				
			||||||
 | 
					//                return sendError("invalid_scope");
 | 
				
			||||||
 | 
					//             }
 | 
				
			||||||
 | 
					//          }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//          let code = ClientCode.new({
 | 
				
			||||||
 | 
					//             user: req.user._id,
 | 
				
			||||||
 | 
					//             client: client._id,
 | 
				
			||||||
 | 
					//             permissions: permissions.map(p => p._id),
 | 
				
			||||||
 | 
					//             validTill: moment().add(30, "minutes").toDate(),
 | 
				
			||||||
 | 
					//             code: randomBytes(16).toString("hex")
 | 
				
			||||||
 | 
					//          });
 | 
				
			||||||
 | 
					//          await ClientCode.save(code);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//          let redir = client.redirect_url === "$local" ? "/code" : client.redirect_url;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//          let ruri = redir + `?code=${code.code}&state=${state}`;
 | 
				
			||||||
 | 
					//          if (nored === "true") {
 | 
				
			||||||
 | 
					//             res.json({
 | 
				
			||||||
 | 
					//                redirect_uri: ruri
 | 
				
			||||||
 | 
					//             })
 | 
				
			||||||
 | 
					//          } else {
 | 
				
			||||||
 | 
					//             res.redirect(ruri);
 | 
				
			||||||
 | 
					//          }
 | 
				
			||||||
 | 
					//       }
 | 
				
			||||||
 | 
					//    } catch (err) {
 | 
				
			||||||
 | 
					//       Logging.error(err);
 | 
				
			||||||
 | 
					//       sendError("server_error")
 | 
				
			||||||
 | 
					//    }
 | 
				
			||||||
 | 
					// })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const GetAuthRoute = (view = false) => Stacker(GetUserMiddleware(false), async (req: Request, res: Response) => {
 | 
				
			||||||
   let { response_type, client_id, redirect_uri, scope, state, nored } = req.query;
 | 
					   let { response_type, client_id, redirect_uri, scope, state, nored } = req.query;
 | 
				
			||||||
   const sendError = (type) => {
 | 
					   const sendError = (type) => {
 | 
				
			||||||
      if (redirect_uri === "$local")
 | 
					      if (redirect_uri === "$local")
 | 
				
			||||||
         redirect_uri = "/code";
 | 
					         redirect_uri = "/code";
 | 
				
			||||||
      res.redirect(redirect_uri += `?error=${type}&state=${state}`);
 | 
					      res.redirect(redirect_uri += `?error=${type}&state=${state}`);
 | 
				
			||||||
   }
 | 
					   }
 | 
				
			||||||
   /**
 | 
					 | 
				
			||||||
    * error
 | 
					 | 
				
			||||||
         REQUIRED.  A single ASCII [USASCII] error code from the
 | 
					 | 
				
			||||||
         following:
 | 
					 | 
				
			||||||
         invalid_request
 | 
					 | 
				
			||||||
               The request is missing a required parameter, includes an
 | 
					 | 
				
			||||||
               invalid parameter value, includes a parameter more than
 | 
					 | 
				
			||||||
               once, or is otherwise malformed.
 | 
					 | 
				
			||||||
         unauthorized_client
 | 
					 | 
				
			||||||
               The client is not authorized to request an authorization
 | 
					 | 
				
			||||||
               code using this method.
 | 
					 | 
				
			||||||
         access_denied
 | 
					 | 
				
			||||||
               The resource owner or authorization server denied the
 | 
					 | 
				
			||||||
               request.
 | 
					 | 
				
			||||||
    */
 | 
					 | 
				
			||||||
   try {
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   const scopes = scope.split(";");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   Logging.debug("Scopes:", scope);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   try {
 | 
				
			||||||
      if (response_type !== "code") {
 | 
					      if (response_type !== "code") {
 | 
				
			||||||
         return sendError("unsupported_response_type");
 | 
					         return sendError("unsupported_response_type");
 | 
				
			||||||
      } else {
 | 
					      } else {
 | 
				
			||||||
         let client = await Client.findOne({ client_id: client_id })
 | 
					
 | 
				
			||||||
 | 
					         let client = await Client.findOne({ client_id: client_id });
 | 
				
			||||||
         if (!client) {
 | 
					         if (!client) {
 | 
				
			||||||
            return sendError("unauthorized_client")
 | 
					            return sendError("unauthorized_client");
 | 
				
			||||||
         }
 | 
					         }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
         if (redirect_uri && client.redirect_url !== redirect_uri) {
 | 
					         if (redirect_uri && client.redirect_url !== redirect_uri) {
 | 
				
			||||||
@ -47,12 +112,74 @@ const AuthRoute = Stacker(GetUserMiddleware(true), async (req: Request, res: Res
 | 
				
			|||||||
         }
 | 
					         }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
         let permissions: IPermission[] = [];
 | 
					         let permissions: IPermission[] = [];
 | 
				
			||||||
         if (scope) {
 | 
					         let proms: PromiseLike<void>[] = [];
 | 
				
			||||||
            let perms = (<string>scope).split(";").filter(e => e !== "read_user").map(p => new ObjectID(p));
 | 
					         if (scopes) {
 | 
				
			||||||
            permissions = await Permission.find({ _id: { $in: perms } })
 | 
					            for (let perm of scopes.filter(e => e !== "read_user")) {
 | 
				
			||||||
 | 
					               proms.push(
 | 
				
			||||||
 | 
					                  Permission.findById(perm).then(p => {
 | 
				
			||||||
 | 
					                     if (!p) return Promise.reject(new Error());
 | 
				
			||||||
 | 
					                     permissions.push(p);
 | 
				
			||||||
 | 
					                  })
 | 
				
			||||||
 | 
					               );
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					         }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (permissions.length != perms.length) {
 | 
					         let err = undefined;
 | 
				
			||||||
               return sendError("invalid_scope");
 | 
					         await Promise.all(proms).catch(e => {
 | 
				
			||||||
 | 
					            err = e;
 | 
				
			||||||
 | 
					         });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					         if (err) {
 | 
				
			||||||
 | 
					            Logging.error(err);
 | 
				
			||||||
 | 
					            return sendError("invalid_scope");
 | 
				
			||||||
 | 
					         }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					         let grant: IGrant | undefined = await Grant.findOne({
 | 
				
			||||||
 | 
					            client: client._id,
 | 
				
			||||||
 | 
					            user: req.user._id
 | 
				
			||||||
 | 
					         })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					         Logging.debug("Grant", grant, permissions);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					         let missing_permissions: IPermission[] = [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					         if (grant) {
 | 
				
			||||||
 | 
					            missing_permissions = grant.permissions.map(perm => permissions.find(p => p._id.equals(perm))).filter(e => !!e);
 | 
				
			||||||
 | 
					         } else {
 | 
				
			||||||
 | 
					            missing_permissions = permissions;
 | 
				
			||||||
 | 
					         }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					         let client_granted_perm = missing_permissions.filter(e => e.grant_type == "client")
 | 
				
			||||||
 | 
					         if (client_granted_perm.length > 0) {
 | 
				
			||||||
 | 
					            return sendError("no_permission")
 | 
				
			||||||
 | 
					         }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					         if (grant && missing_permissions.length > 0) {
 | 
				
			||||||
 | 
					            await new Promise<void>((yes, no) => GetUserMiddleware(false, true)(req, res, (err?: Error) => err ? no(err) : yes())); // Maybe unresolved when redirect is happening
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (view) {
 | 
				
			||||||
 | 
					               res.send(GetAuthPage(req.__, client.name, permissions.map(perm => {
 | 
				
			||||||
 | 
					                  return {
 | 
				
			||||||
 | 
					                     name: perm.name,
 | 
				
			||||||
 | 
					                     description: perm.description,
 | 
				
			||||||
 | 
					                     logo: client.logo
 | 
				
			||||||
 | 
					                  }
 | 
				
			||||||
 | 
					               })));
 | 
				
			||||||
 | 
					               return;
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					               if (req.body.allow = "true") {
 | 
				
			||||||
 | 
					                  if (!grant)
 | 
				
			||||||
 | 
					                     grant = Grant.new({
 | 
				
			||||||
 | 
					                        client: client._id,
 | 
				
			||||||
 | 
					                        user: req.user._id,
 | 
				
			||||||
 | 
					                        permissions: []
 | 
				
			||||||
 | 
					                     });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                  grant.permissions.push(...missing_permissions.map(e => e._id));
 | 
				
			||||||
 | 
					                  await Grant.save(grant);
 | 
				
			||||||
 | 
					               } else {
 | 
				
			||||||
 | 
					                  return sendError("access_denied");
 | 
				
			||||||
 | 
					               }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
         }
 | 
					         }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -66,7 +193,6 @@ const AuthRoute = Stacker(GetUserMiddleware(true), async (req: Request, res: Res
 | 
				
			|||||||
         await ClientCode.save(code);
 | 
					         await ClientCode.save(code);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
         let redir = client.redirect_url === "$local" ? "/code" : client.redirect_url;
 | 
					         let redir = client.redirect_url === "$local" ? "/code" : client.redirect_url;
 | 
				
			||||||
 | 
					 | 
				
			||||||
         let ruri = redir + `?code=${code.code}&state=${state}`;
 | 
					         let ruri = redir + `?code=${code.code}&state=${state}`;
 | 
				
			||||||
         if (nored === "true") {
 | 
					         if (nored === "true") {
 | 
				
			||||||
            res.json({
 | 
					            res.json({
 | 
				
			||||||
@ -80,5 +206,6 @@ const AuthRoute = Stacker(GetUserMiddleware(true), async (req: Request, res: Res
 | 
				
			|||||||
      Logging.error(err);
 | 
					      Logging.error(err);
 | 
				
			||||||
      sendError("server_error")
 | 
					      sendError("server_error")
 | 
				
			||||||
   }
 | 
					   }
 | 
				
			||||||
})
 | 
					});
 | 
				
			||||||
export default AuthRoute;
 | 
					
 | 
				
			||||||
 | 
					export default GetAuthRoute;
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,5 @@
 | 
				
			|||||||
import { Router } from "express";
 | 
					import { Router } from "express";
 | 
				
			||||||
import AuthRoute from "./auth";
 | 
					import GetAuthRoute from "./auth";
 | 
				
			||||||
import JWTRoute from "./jwt";
 | 
					import JWTRoute from "./jwt";
 | 
				
			||||||
import Public from "./public";
 | 
					import Public from "./public";
 | 
				
			||||||
import RefreshTokenRoute from "./refresh";
 | 
					import RefreshTokenRoute from "./refresh";
 | 
				
			||||||
@ -19,7 +19,7 @@ const OAuthRoue: Router = Router();
 | 
				
			|||||||
 * @apiParam {String} state State, that will be passed to redirect_uri for client
 | 
					 * @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
 | 
					 * @apiParam {String} nored Deactivates the Redirect response from server and instead returns the redirect URI in JSON response
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
OAuthRoue.post("/auth", AuthRoute);
 | 
					OAuthRoue.post("/auth", GetAuthRoute(false));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * @api {get} /oauth/jwt
 | 
					 * @api {get} /oauth/jwt
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										23
									
								
								src/models/grants.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								src/models/grants.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,23 @@
 | 
				
			|||||||
 | 
					import DB from "../database";
 | 
				
			||||||
 | 
					import { ModelDataBase } from "@hibas123/safe_mongo/lib/model";
 | 
				
			||||||
 | 
					import { ObjectID } from "mongodb";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export interface IGrant extends ModelDataBase {
 | 
				
			||||||
 | 
					   user: ObjectID;
 | 
				
			||||||
 | 
					   client: ObjectID;
 | 
				
			||||||
 | 
					   permissions: ObjectID[];
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const Grant = DB.addModel<IGrant>({
 | 
				
			||||||
 | 
					   name: "grant",
 | 
				
			||||||
 | 
					   versions: [{
 | 
				
			||||||
 | 
					      migration: () => { },
 | 
				
			||||||
 | 
					      schema: {
 | 
				
			||||||
 | 
					         user: { type: ObjectID },
 | 
				
			||||||
 | 
					         client: { type: ObjectID },
 | 
				
			||||||
 | 
					         permissions: { type: ObjectID, array: true }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					   }]
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default Grant;
 | 
				
			||||||
@ -1,12 +1,12 @@
 | 
				
			|||||||
import DB from "../database";
 | 
					import DB from "../database";
 | 
				
			||||||
import { ModelDataBase } from "@hibas123/safe_mongo/lib/model";
 | 
					import { ModelDataBase } from "@hibas123/safe_mongo/lib/model";
 | 
				
			||||||
import { ObjectID } from "mongodb";
 | 
					import { ObjectID } from "mongodb";
 | 
				
			||||||
import { v4 } from "uuid";
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
export interface IPermission extends ModelDataBase {
 | 
					export interface IPermission extends ModelDataBase {
 | 
				
			||||||
   name: string;
 | 
					   name: string;
 | 
				
			||||||
   description: string;
 | 
					   description: string;
 | 
				
			||||||
   client: ObjectID;
 | 
					   client: ObjectID;
 | 
				
			||||||
 | 
					   grant_type: "user" | "client";
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const Permission = DB.addModel<IPermission>({
 | 
					const Permission = DB.addModel<IPermission>({
 | 
				
			||||||
@ -18,6 +18,14 @@ const Permission = DB.addModel<IPermission>({
 | 
				
			|||||||
         description: { type: String },
 | 
					         description: { type: String },
 | 
				
			||||||
         client: { type: ObjectID }
 | 
					         client: { type: ObjectID }
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					   }, {
 | 
				
			||||||
 | 
					      migration: (old) => { old.grant_type = "user" },
 | 
				
			||||||
 | 
					      schema: {
 | 
				
			||||||
 | 
					         name: { type: String },
 | 
				
			||||||
 | 
					         description: { type: String },
 | 
				
			||||||
 | 
					         client: { type: ObjectID },
 | 
				
			||||||
 | 
					         grant_type: { type: String, default: "user" }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
   }]
 | 
					   }]
 | 
				
			||||||
})
 | 
					})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -71,8 +71,11 @@ export default async function TestData() {
 | 
				
			|||||||
         name: "TestPerm",
 | 
					         name: "TestPerm",
 | 
				
			||||||
         description: "Permission just for testing purposes",
 | 
					         description: "Permission just for testing purposes",
 | 
				
			||||||
         client: c._id
 | 
					         client: c._id
 | 
				
			||||||
      })
 | 
					      });
 | 
				
			||||||
      Permission.save(perm);
 | 
					
 | 
				
			||||||
 | 
					      await (await (Permission as any)._collection).insertOne(perm);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // Permission.save(perm);
 | 
				
			||||||
   }
 | 
					   }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
   let r = await RegCode.findOne({ token: "test" });
 | 
					   let r = await RegCode.findOne({ token: "test" });
 | 
				
			||||||
 | 
				
			|||||||
@ -53,56 +53,62 @@ ViewRouter.get(
 | 
				
			|||||||
   }
 | 
					   }
 | 
				
			||||||
);
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ViewRouter.get(
 | 
					 | 
				
			||||||
   "/auth",
 | 
					 | 
				
			||||||
   Stacker(GetUserMiddleware(false, true), async (req, res) => {
 | 
					 | 
				
			||||||
      let {
 | 
					 | 
				
			||||||
         scope,
 | 
					 | 
				
			||||||
         redirect_uri,
 | 
					 | 
				
			||||||
         state,
 | 
					 | 
				
			||||||
         client_id
 | 
					 | 
				
			||||||
      }: { [key: string]: string } = req.query;
 | 
					 | 
				
			||||||
      const sendError = type => {
 | 
					 | 
				
			||||||
         res.redirect((redirect_uri += `?error=${type}&state=${state}`));
 | 
					 | 
				
			||||||
      };
 | 
					 | 
				
			||||||
      let client = await Client.findOne({ client_id: client_id });
 | 
					 | 
				
			||||||
      if (!client) {
 | 
					 | 
				
			||||||
         return sendError("unauthorized_client");
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
      let permissions: IPermission[] = [];
 | 
					import GetAuthRoute from "../api/oauth/auth";
 | 
				
			||||||
      let proms: PromiseLike<void>[] = [];
 | 
					
 | 
				
			||||||
      if (scope) {
 | 
					ViewRouter.get("/auth", GetAuthRoute(true))
 | 
				
			||||||
         for (let perm of scope.split(";").filter(e => e !== "read_user")) {
 | 
					
 | 
				
			||||||
            proms.push(
 | 
					// ViewRouter.get(
 | 
				
			||||||
               Permission.findById(perm).then(p => {
 | 
					//    "/auth",
 | 
				
			||||||
                  if (!p) return Promise.reject(new Error());
 | 
					//    Stacker(GetUserMiddleware(false, true), async (req, res) => {
 | 
				
			||||||
                  permissions.push(p);
 | 
					//       let {
 | 
				
			||||||
               })
 | 
					//          scope,
 | 
				
			||||||
            );
 | 
					//          redirect_uri,
 | 
				
			||||||
         }
 | 
					//          state,
 | 
				
			||||||
      }
 | 
					//          client_id
 | 
				
			||||||
      let err = false;
 | 
					//       }: { [key: string]: string } = req.query;
 | 
				
			||||||
      await Promise.all(proms).catch(e => {
 | 
					//       const sendError = type => {
 | 
				
			||||||
         err = true;
 | 
					//          res.redirect((redirect_uri += `?error=${type}&state=${state}`));
 | 
				
			||||||
      });
 | 
					//       };
 | 
				
			||||||
      Logging.debug(err);
 | 
					
 | 
				
			||||||
      if (err) {
 | 
					//       let client = await Client.findOne({ client_id: client_id });
 | 
				
			||||||
         return sendError("invalid_scope");
 | 
					//       if (!client) {
 | 
				
			||||||
      }
 | 
					//          return sendError("unauthorized_client");
 | 
				
			||||||
      let scopes = await Promise.all(
 | 
					//       }
 | 
				
			||||||
         permissions.map(async perm => {
 | 
					
 | 
				
			||||||
            let client = await Client.findById(perm.client);
 | 
					//       let permissions: IPermission[] = [];
 | 
				
			||||||
            return {
 | 
					//       let proms: PromiseLike<void>[] = [];
 | 
				
			||||||
               name: perm.name,
 | 
					//       if (scope) {
 | 
				
			||||||
               description: perm.description,
 | 
					//          for (let perm of scope.split(";").filter(e => e !== "read_user")) {
 | 
				
			||||||
               logo: client.logo
 | 
					//             proms.push(
 | 
				
			||||||
            };
 | 
					//                Permission.findById(perm).then(p => {
 | 
				
			||||||
         })
 | 
					//                   if (!p) return Promise.reject(new Error());
 | 
				
			||||||
      );
 | 
					//                   permissions.push(p);
 | 
				
			||||||
      res.send(GetAuthPage(req.__, client.name, scopes));
 | 
					//                })
 | 
				
			||||||
   })
 | 
					//             );
 | 
				
			||||||
);
 | 
					//          }
 | 
				
			||||||
 | 
					//       }
 | 
				
			||||||
 | 
					//       let err = false;
 | 
				
			||||||
 | 
					//       await Promise.all(proms).catch(e => {
 | 
				
			||||||
 | 
					//          err = true;
 | 
				
			||||||
 | 
					//       });
 | 
				
			||||||
 | 
					//       Logging.debug(err);
 | 
				
			||||||
 | 
					//       if (err) {
 | 
				
			||||||
 | 
					//          return sendError("invalid_scope");
 | 
				
			||||||
 | 
					//       }
 | 
				
			||||||
 | 
					//       let scopes = await Promise.all(
 | 
				
			||||||
 | 
					//          permissions.map(async perm => {
 | 
				
			||||||
 | 
					//             let client = await Client.findById(perm.client);
 | 
				
			||||||
 | 
					//             return {
 | 
				
			||||||
 | 
					//                name: perm.name,
 | 
				
			||||||
 | 
					//                description: perm.description,
 | 
				
			||||||
 | 
					//                logo: client.logo
 | 
				
			||||||
 | 
					//             };
 | 
				
			||||||
 | 
					//          })
 | 
				
			||||||
 | 
					//       );
 | 
				
			||||||
 | 
					//       res.send(GetAuthPage(req.__, client.name, scopes));
 | 
				
			||||||
 | 
					//    })
 | 
				
			||||||
 | 
					// );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if (config.core.dev) {
 | 
					if (config.core.dev) {
 | 
				
			||||||
   const logo =
 | 
					   const logo =
 | 
				
			||||||
 | 
				
			|||||||
@ -44,7 +44,9 @@
 | 
				
			|||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
   </div>
 | 
					   </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
   <form method="post" action="/api/oauth/auth?" id="hidden_form" style="display: none;"></form>
 | 
					   <form method="post" action="/api/oauth/auth?" id="hidden_form" style="display: none;">
 | 
				
			||||||
 | 
					      <input name="accept" value="true" />
 | 
				
			||||||
 | 
					   </form>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
</body>
 | 
					</body>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user