Making grants and authentication now possible.

This commit is contained in:
Fabian Stamm 2020-03-18 11:00:57 +01:00
parent 44d02b0110
commit d94e83b468
3 changed files with 141 additions and 112 deletions

2
.vscode/launch.json vendored
View File

@ -5,7 +5,7 @@
"version": "0.2.0", "version": "0.2.0",
"configurations": [ "configurations": [
{ {
"type": "node", "type": "pwa-node",
"request": "launch", "request": "launch",
"name": "Launch Program", "name": "Launch Program",
"program": "${workspaceFolder}/lib/index.js", "program": "${workspaceFolder}/lib/index.js",

View File

@ -11,5 +11,7 @@
"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", "No login token": "No login token",
"Login token invalid": "Login token invalid" "Login token invalid": "Login token invalid",
"Authorize %s": "Authorize %s",
"By clicking on ALLOW, you allow this app to access the requested recources.": "By clicking on ALLOW, you allow this app to access the requested recources."
} }

View File

@ -84,13 +84,20 @@ import GetAuthPage from "../../views/authorize";
// } // }
// }) // })
const GetAuthRoute = (view = false) => Stacker(GetUserMiddleware(false), async (req: Request, res: Response) => { const GetAuthRoute = (view = false) =>
let { response_type, client_id, redirect_uri, scope, state, nored } = req.query; Stacker(GetUserMiddleware(false), async (req: Request, res: Response) => {
const sendError = (type) => { let {
if (redirect_uri === "$local") response_type,
redirect_uri = "/code"; client_id,
res.redirect(redirect_uri += `?error=${type}&state=${state}`); 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}`));
};
const scopes = scope.split(";"); const scopes = scope.split(";");
@ -100,7 +107,6 @@ const GetAuthRoute = (view = false) => Stacker(GetUserMiddleware(false), async (
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");
@ -108,7 +114,9 @@ const GetAuthRoute = (view = false) => Stacker(GetUserMiddleware(false), async (
if (redirect_uri && client.redirect_url !== redirect_uri) { if (redirect_uri && client.redirect_url !== redirect_uri) {
Logging.log(redirect_uri, client.redirect_url); 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!"); 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[] = []; let permissions: IPermission[] = [];
@ -137,37 +145,51 @@ const GetAuthRoute = (view = false) => Stacker(GetUserMiddleware(false), async (
let grant: IGrant | undefined = await Grant.findOne({ let grant: IGrant | undefined = await Grant.findOne({
client: client._id, client: client._id,
user: req.user._id user: req.user._id
}) });
Logging.debug("Grant", grant, permissions); Logging.debug("Grant", grant, permissions);
let missing_permissions: IPermission[] = []; let missing_permissions: IPermission[] = [];
if (grant) { if (grant) {
missing_permissions = grant.permissions.map(perm => permissions.find(p => p._id.equals(perm))).filter(e => !!e); missing_permissions = grant.permissions
.map(perm => permissions.find(p => p._id.equals(perm)))
.filter(e => !!e);
} else { } else {
missing_permissions = permissions; missing_permissions = permissions;
} }
let client_granted_perm = missing_permissions.filter(e => e.grant_type == "client") let client_granted_perm = missing_permissions.filter(
e => e.grant_type == "client"
);
if (client_granted_perm.length > 0) { if (client_granted_perm.length > 0) {
return sendError("no_permission") return sendError("no_permission");
} }
if (grant && missing_permissions.length > 0) { 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 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) { if (view) {
res.send(GetAuthPage(req.__, client.name, permissions.map(perm => { res.send(
GetAuthPage(
req.__,
client.name,
permissions.map(perm => {
return { return {
name: perm.name, name: perm.name,
description: perm.description, description: perm.description,
logo: client.logo logo: client.logo
} };
}))); })
)
);
return; return;
} else { } else {
if (req.body.allow = "true") { if ((req.body.allow = "true")) {
if (!grant) if (!grant)
grant = Grant.new({ grant = Grant.new({
client: client._id, client: client._id,
@ -175,7 +197,9 @@ const GetAuthRoute = (view = false) => Stacker(GetUserMiddleware(false), async (
permissions: [] permissions: []
}); });
grant.permissions.push(...missing_permissions.map(e => e._id)); grant.permissions.push(
...missing_permissions.map(e => e._id)
);
await Grant.save(grant); await Grant.save(grant);
} else { } else {
return sendError("access_denied"); return sendError("access_denied");
@ -187,25 +211,28 @@ const GetAuthRoute = (view = false) => Stacker(GetUserMiddleware(false), async (
user: req.user._id, user: req.user._id,
client: client._id, client: client._id,
permissions: permissions.map(p => p._id), permissions: permissions.map(p => p._id),
validTill: moment().add(30, "minutes").toDate(), validTill: moment()
.add(30, "minutes")
.toDate(),
code: randomBytes(16).toString("hex") code: randomBytes(16).toString("hex")
}); });
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({
redirect_uri: ruri redirect_uri: ruri
}) });
} else { } else {
res.redirect(ruri); res.redirect(ruri);
} }
} }
} catch (err) { } catch (err) {
Logging.error(err); Logging.error(err);
sendError("server_error") sendError("server_error");
} }
}); });
export default GetAuthRoute; export default GetAuthRoute;