Updating dependencies and switching to ESModules where possible
Some checks failed
CI / build (push) Has been cancelled
Some checks failed
CI / build (push) Has been cancelled
This commit is contained in:
@ -1,15 +1,15 @@
|
||||
import Stacker from "../middlewares/stacker";
|
||||
import { GetUserMiddleware } from "../middlewares/user";
|
||||
import Stacker from "../middlewares/stacker.js";
|
||||
import { GetUserMiddleware } from "../middlewares/user.js";
|
||||
import { Request, Response } from "express";
|
||||
import Client from "../../models/client";
|
||||
import Client from "../../models/client.js";
|
||||
import Logging from "@hibas123/nodelogging";
|
||||
import Permission, { IPermission } from "../../models/permissions";
|
||||
import ClientCode from "../../models/client_code";
|
||||
import Permission, { IPermission } from "../../models/permissions.js";
|
||||
import ClientCode from "../../models/client_code.js";
|
||||
import moment = require("moment");
|
||||
import { randomBytes } from "crypto";
|
||||
// import { ObjectId } from "bson";
|
||||
import Grant, { IGrant } from "../../models/grants";
|
||||
import GetAuthPage from "../../views/authorize";
|
||||
import Grant, { IGrant } from "../../models/grants.js";
|
||||
import GetAuthPage from "../../views/authorize.js";
|
||||
import { ObjectId } from "mongodb";
|
||||
|
||||
// const AuthRoute = Stacker(GetUserMiddleware(true), async (req: Request, res: Response) => {
|
||||
|
@ -1,73 +1,73 @@
|
||||
import { Router } from "express";
|
||||
import GetAuthRoute from "./auth";
|
||||
import JWTRoute from "./jwt";
|
||||
import Public from "./public";
|
||||
import RefreshTokenRoute from "./refresh";
|
||||
import ProfileRoute from "./profile";
|
||||
|
||||
const OAuthRoute: Router = Router();
|
||||
/**
|
||||
* @api {post} /oauth/auth
|
||||
* @apiName OAuthAuth
|
||||
*
|
||||
* @apiGroup oauth
|
||||
* @apiPermission user Special required
|
||||
*
|
||||
* @apiParam {String} response_type must be "code" others are not supported
|
||||
* @apiParam {String} client_id ClientID
|
||||
* @apiParam {String} redirect_uri The URI to redirect with code
|
||||
* @apiParam {String} scope Scope that contains the requested permissions (comma seperated list of permissions)
|
||||
* @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
|
||||
*/
|
||||
OAuthRoute.post("/auth", GetAuthRoute(false));
|
||||
|
||||
/**
|
||||
* @api {get} /oauth/jwt
|
||||
* @apiName OAuthJwt
|
||||
*
|
||||
* @apiGroup oauth
|
||||
* @apiPermission none
|
||||
*
|
||||
* @apiParam {String} refreshtoken
|
||||
*
|
||||
* @apiSuccess {String} token The JWT that allowes the application to access the recources granted for refresh token
|
||||
*/
|
||||
OAuthRoute.get("/jwt", JWTRoute);
|
||||
|
||||
/**
|
||||
* @api {get} /oauth/public
|
||||
* @apiName OAuthPublic
|
||||
*
|
||||
* @apiGroup oauth
|
||||
* @apiPermission none
|
||||
*
|
||||
* @apiSuccess {String} public_key The applications public_key. Used to verify JWT.
|
||||
*/
|
||||
OAuthRoute.get("/public", Public);
|
||||
|
||||
/**
|
||||
* @api {get} /oauth/refresh
|
||||
* @apiName OAuthRefreshGet
|
||||
*
|
||||
* @apiGroup oauth
|
||||
*/
|
||||
OAuthRoute.get("/refresh", RefreshTokenRoute);
|
||||
|
||||
/**
|
||||
* @api {post} /oauth/refresh
|
||||
* @apiName OAuthRefreshPost
|
||||
*
|
||||
* @apiGroup oauth
|
||||
*/
|
||||
OAuthRoute.post("/refresh", RefreshTokenRoute);
|
||||
|
||||
/**
|
||||
* @api {get} /oauth/profile
|
||||
* @apiName OAuthProfile
|
||||
*
|
||||
* @apiGroup oauth
|
||||
*/
|
||||
OAuthRoute.get("/profile", ProfileRoute);
|
||||
|
||||
export default OAuthRoute;
|
||||
import { Router } from "express";
|
||||
import GetAuthRoute from "./auth.js";
|
||||
import JWTRoute from "./jwt.js";
|
||||
import Public from "./public.js";
|
||||
import RefreshTokenRoute from "./refresh.js";
|
||||
import ProfileRoute from "./profile.js";
|
||||
|
||||
const OAuthRoute: Router = Router();
|
||||
/**
|
||||
* @api {post} /oauth/auth
|
||||
* @apiName OAuthAuth
|
||||
*
|
||||
* @apiGroup oauth
|
||||
* @apiPermission user Special required
|
||||
*
|
||||
* @apiParam {String} response_type must be "code" others are not supported
|
||||
* @apiParam {String} client_id ClientID
|
||||
* @apiParam {String} redirect_uri The URI to redirect with code
|
||||
* @apiParam {String} scope Scope that contains the requested permissions (comma seperated list of permissions)
|
||||
* @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
|
||||
*/
|
||||
OAuthRoute.post("/auth", GetAuthRoute(false));
|
||||
|
||||
/**
|
||||
* @api {get} /oauth/jwt
|
||||
* @apiName OAuthJwt
|
||||
*
|
||||
* @apiGroup oauth
|
||||
* @apiPermission none
|
||||
*
|
||||
* @apiParam {String} refreshtoken
|
||||
*
|
||||
* @apiSuccess {String} token The JWT that allowes the application to access the recources granted for refresh token
|
||||
*/
|
||||
OAuthRoute.get("/jwt", JWTRoute);
|
||||
|
||||
/**
|
||||
* @api {get} /oauth/public
|
||||
* @apiName OAuthPublic
|
||||
*
|
||||
* @apiGroup oauth
|
||||
* @apiPermission none
|
||||
*
|
||||
* @apiSuccess {String} public_key The applications public_key. Used to verify JWT.
|
||||
*/
|
||||
OAuthRoute.get("/public", Public);
|
||||
|
||||
/**
|
||||
* @api {get} /oauth/refresh
|
||||
* @apiName OAuthRefreshGet
|
||||
*
|
||||
* @apiGroup oauth
|
||||
*/
|
||||
OAuthRoute.get("/refresh", RefreshTokenRoute);
|
||||
|
||||
/**
|
||||
* @api {post} /oauth/refresh
|
||||
* @apiName OAuthRefreshPost
|
||||
*
|
||||
* @apiGroup oauth
|
||||
*/
|
||||
OAuthRoute.post("/refresh", RefreshTokenRoute);
|
||||
|
||||
/**
|
||||
* @api {get} /oauth/profile
|
||||
* @apiName OAuthProfile
|
||||
*
|
||||
* @apiGroup oauth
|
||||
*/
|
||||
OAuthRoute.get("/profile", ProfileRoute);
|
||||
|
||||
export default OAuthRoute;
|
||||
|
@ -1,43 +1,43 @@
|
||||
import { Request, Response } from "express";
|
||||
import promiseMiddleware from "../../helper/promiseMiddleware";
|
||||
import RequestError, { HttpStatusCode } from "../../helper/request_error";
|
||||
import RefreshToken from "../../models/refresh_token";
|
||||
import User from "../../models/user";
|
||||
import Client from "../../models/client";
|
||||
import { getAccessTokenJWT } from "../../helper/jwt";
|
||||
|
||||
const JWTRoute = promiseMiddleware(async (req: Request, res: Response) => {
|
||||
let { refreshtoken } = req.query as { [key: string]: string };
|
||||
if (!refreshtoken)
|
||||
throw new RequestError(
|
||||
req.__("Refresh token not set"),
|
||||
HttpStatusCode.BAD_REQUEST
|
||||
);
|
||||
|
||||
let token = await RefreshToken.findOne({ token: refreshtoken });
|
||||
if (!token)
|
||||
throw new RequestError(
|
||||
req.__("Invalid token"),
|
||||
HttpStatusCode.BAD_REQUEST
|
||||
);
|
||||
|
||||
let user = await User.findById(token.user);
|
||||
if (!user) {
|
||||
token.valid = false;
|
||||
await RefreshToken.save(token);
|
||||
throw new RequestError(
|
||||
req.__("Invalid token"),
|
||||
HttpStatusCode.BAD_REQUEST
|
||||
);
|
||||
}
|
||||
|
||||
let client = await Client.findById(token.client);
|
||||
|
||||
let jwt = await getAccessTokenJWT({
|
||||
user,
|
||||
permissions: token.permissions,
|
||||
client,
|
||||
});
|
||||
res.json({ token: jwt });
|
||||
});
|
||||
export default JWTRoute;
|
||||
import { Request, Response } from "express";
|
||||
import promiseMiddleware from "../../helper/promiseMiddleware.js";
|
||||
import RequestError, { HttpStatusCode } from "../../helper/request_error.js";
|
||||
import RefreshToken from "../../models/refresh_token.js";
|
||||
import User from "../../models/user.js";
|
||||
import Client from "../../models/client.js";
|
||||
import { getAccessTokenJWT } from "../../helper/jwt.js";
|
||||
|
||||
const JWTRoute = promiseMiddleware(async (req: Request, res: Response) => {
|
||||
let { refreshtoken } = req.query as { [key: string]: string };
|
||||
if (!refreshtoken)
|
||||
throw new RequestError(
|
||||
req.__("Refresh token not set"),
|
||||
HttpStatusCode.BAD_REQUEST
|
||||
);
|
||||
|
||||
let token = await RefreshToken.findOne({ token: refreshtoken });
|
||||
if (!token)
|
||||
throw new RequestError(
|
||||
req.__("Invalid token"),
|
||||
HttpStatusCode.BAD_REQUEST
|
||||
);
|
||||
|
||||
let user = await User.findById(token.user);
|
||||
if (!user) {
|
||||
token.valid = false;
|
||||
await RefreshToken.save(token);
|
||||
throw new RequestError(
|
||||
req.__("Invalid token"),
|
||||
HttpStatusCode.BAD_REQUEST
|
||||
);
|
||||
}
|
||||
|
||||
let client = await Client.findById(token.client);
|
||||
|
||||
let jwt = await getAccessTokenJWT({
|
||||
user,
|
||||
permissions: token.permissions,
|
||||
client,
|
||||
});
|
||||
res.json({ token: jwt });
|
||||
});
|
||||
export default JWTRoute;
|
||||
|
@ -1,6 +1,6 @@
|
||||
import Mail from "../../models/mail";
|
||||
import { GetClientApiAuthMiddleware } from "../middlewares/client";
|
||||
import Stacker from "../middlewares/stacker";
|
||||
import Mail from "../../models/mail.js";
|
||||
import { GetClientApiAuthMiddleware } from "../middlewares/client.js";
|
||||
import Stacker from "../middlewares/stacker.js";
|
||||
import { Request, Response } from "express";
|
||||
import Logging from "@hibas123/nodelogging";
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { Request, Response } from "express";
|
||||
import { public_key } from "../../keys";
|
||||
|
||||
export default function Public(req: Request, res: Response) {
|
||||
res.json({ public_key: public_key });
|
||||
}
|
||||
import { Request, Response } from "express";
|
||||
import { public_key } from "../../keys.js";
|
||||
|
||||
export default function Public(req: Request, res: Response) {
|
||||
res.json({ public_key: public_key });
|
||||
}
|
||||
|
@ -1,122 +1,122 @@
|
||||
import { Request, Response } from "express";
|
||||
import RequestError, { HttpStatusCode } from "../../helper/request_error";
|
||||
import User from "../../models/user";
|
||||
import Client from "../../models/client";
|
||||
import {
|
||||
getAccessTokenJWT,
|
||||
getIDToken,
|
||||
AccessTokenJWTExp,
|
||||
} from "../../helper/jwt";
|
||||
import Stacker from "../middlewares/stacker";
|
||||
import { GetClientAuthMiddleware } from "../middlewares/client";
|
||||
import ClientCode from "../../models/client_code";
|
||||
import Mail from "../../models/mail";
|
||||
import { randomBytes } from "crypto";
|
||||
import moment = require("moment");
|
||||
// import { JWTExpDur } from "../../keys";
|
||||
import RefreshToken from "../../models/refresh_token";
|
||||
import { getEncryptionKey } from "../../helper/user_key";
|
||||
import { refreshTokenValidTime } from "../../config";
|
||||
|
||||
// TODO:
|
||||
/*
|
||||
For example, the authorization server could employ refresh token
|
||||
rotation in which a new refresh token is issued with every access
|
||||
token refresh response. The previous refresh token is invalidated but retained by the authorization server. If a refresh token is
|
||||
compromised and subsequently used by both the attacker and the
|
||||
legitimate client, one of them will present an invalidated refresh
|
||||
token, which will inform the authorization server of the breach.
|
||||
*/
|
||||
|
||||
const RefreshTokenRoute = Stacker(
|
||||
GetClientAuthMiddleware(false, false, true),
|
||||
async (req: Request, res: Response) => {
|
||||
let grant_type = req.query.grant_type || req.body.grant_type;
|
||||
if (!grant_type || grant_type === "authorization_code") {
|
||||
let code = req.query.code || req.body.code;
|
||||
let nonce = req.query.nonce || req.body.nonce;
|
||||
|
||||
let c = await ClientCode.findOne({ code: code });
|
||||
if (!c || moment(c.validTill).isBefore()) {
|
||||
throw new RequestError(
|
||||
req.__("Invalid code"),
|
||||
HttpStatusCode.BAD_REQUEST
|
||||
);
|
||||
}
|
||||
|
||||
let client = await Client.findById(c.client);
|
||||
|
||||
let user = await User.findById(c.user);
|
||||
let mails = await Promise.all(user.mails.map((m) => Mail.findOne(m)));
|
||||
|
||||
let token = RefreshToken.new({
|
||||
user: c.user,
|
||||
client: c.client,
|
||||
permissions: c.permissions,
|
||||
token: randomBytes(16).toString("hex"),
|
||||
valid: true,
|
||||
validTill: moment().add(refreshTokenValidTime).toDate(),
|
||||
});
|
||||
await RefreshToken.save(token);
|
||||
await ClientCode.delete(c);
|
||||
|
||||
let mail = mails.find((e) => e.primary);
|
||||
if (!mail) mail = mails[0];
|
||||
|
||||
res.json({
|
||||
refresh_token: token.token,
|
||||
token: token.token,
|
||||
access_token: await getAccessTokenJWT({
|
||||
client: client,
|
||||
user: user,
|
||||
permissions: c.permissions,
|
||||
}),
|
||||
token_type: "bearer",
|
||||
expires_in: AccessTokenJWTExp.asSeconds(),
|
||||
profile: {
|
||||
uid: user.uid,
|
||||
email: mail ? mail.mail : "",
|
||||
name: user.name,
|
||||
enc_key: getEncryptionKey(user, client),
|
||||
},
|
||||
id_token: getIDToken(user, client.client_id, nonce),
|
||||
});
|
||||
} else if (grant_type === "refresh_token") {
|
||||
let refresh_token = req.query.refresh_token || req.body.refresh_token;
|
||||
if (!refresh_token)
|
||||
throw new RequestError(
|
||||
req.__("refresh_token not set"),
|
||||
HttpStatusCode.BAD_REQUEST
|
||||
);
|
||||
|
||||
let token = await RefreshToken.findOne({ token: refresh_token });
|
||||
if (!token || !token.valid || moment(token.validTill).isBefore())
|
||||
throw new RequestError(
|
||||
req.__("Invalid token"),
|
||||
HttpStatusCode.BAD_REQUEST
|
||||
);
|
||||
|
||||
token.validTill = moment().add(refreshTokenValidTime).toDate();
|
||||
await RefreshToken.save(token);
|
||||
|
||||
let user = await User.findById(token.user);
|
||||
let client = await Client.findById(token.client);
|
||||
let jwt = await getAccessTokenJWT({
|
||||
user,
|
||||
client,
|
||||
permissions: token.permissions,
|
||||
});
|
||||
res.json({
|
||||
access_token: jwt,
|
||||
expires_in: AccessTokenJWTExp.asSeconds(),
|
||||
});
|
||||
} else {
|
||||
throw new RequestError(
|
||||
"invalid grant_type",
|
||||
HttpStatusCode.BAD_REQUEST
|
||||
);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
export default RefreshTokenRoute;
|
||||
import { Request, Response } from "express";
|
||||
import RequestError, { HttpStatusCode } from "../../helper/request_error.js";
|
||||
import User from "../../models/user.js";
|
||||
import Client from "../../models/client.js";
|
||||
import {
|
||||
getAccessTokenJWT,
|
||||
getIDToken,
|
||||
AccessTokenJWTExp,
|
||||
} from "../../helper/jwt.js";
|
||||
import Stacker from "../middlewares/stacker.js";
|
||||
import { GetClientAuthMiddleware } from "../middlewares/client.js";
|
||||
import ClientCode from "../../models/client_code.js";
|
||||
import Mail from "../../models/mail.js";
|
||||
import { randomBytes } from "crypto";
|
||||
import moment = require("moment");
|
||||
// import { JWTExpDur } from "../../keys";
|
||||
import RefreshToken from "../../models/refresh_token.js";
|
||||
import { getEncryptionKey } from "../../helper/user_key.js";
|
||||
import { refreshTokenValidTime } from "../../config.js";
|
||||
|
||||
// TODO:
|
||||
/*
|
||||
For example, the authorization server could employ refresh token
|
||||
rotation in which a new refresh token is issued with every access
|
||||
token refresh response. The previous refresh token is invalidated but retained by the authorization server. If a refresh token is
|
||||
compromised and subsequently used by both the attacker and the
|
||||
legitimate client, one of them will present an invalidated refresh
|
||||
token, which will inform the authorization server of the breach.
|
||||
*/
|
||||
|
||||
const RefreshTokenRoute = Stacker(
|
||||
GetClientAuthMiddleware(false, false, true),
|
||||
async (req: Request, res: Response) => {
|
||||
let grant_type = req.query.grant_type || req.body.grant_type;
|
||||
if (!grant_type || grant_type === "authorization_code") {
|
||||
let code = req.query.code || req.body.code;
|
||||
let nonce = req.query.nonce || req.body.nonce;
|
||||
|
||||
let c = await ClientCode.findOne({ code: code });
|
||||
if (!c || moment(c.validTill).isBefore()) {
|
||||
throw new RequestError(
|
||||
req.__("Invalid code"),
|
||||
HttpStatusCode.BAD_REQUEST
|
||||
);
|
||||
}
|
||||
|
||||
let client = await Client.findById(c.client);
|
||||
|
||||
let user = await User.findById(c.user);
|
||||
let mails = await Promise.all(user.mails.map((m) => Mail.findOne(m)));
|
||||
|
||||
let token = RefreshToken.new({
|
||||
user: c.user,
|
||||
client: c.client,
|
||||
permissions: c.permissions,
|
||||
token: randomBytes(16).toString("hex"),
|
||||
valid: true,
|
||||
validTill: moment().add(refreshTokenValidTime).toDate(),
|
||||
});
|
||||
await RefreshToken.save(token);
|
||||
await ClientCode.delete(c);
|
||||
|
||||
let mail = mails.find((e) => e.primary);
|
||||
if (!mail) mail = mails[0];
|
||||
|
||||
res.json({
|
||||
refresh_token: token.token,
|
||||
token: token.token,
|
||||
access_token: await getAccessTokenJWT({
|
||||
client: client,
|
||||
user: user,
|
||||
permissions: c.permissions,
|
||||
}),
|
||||
token_type: "bearer",
|
||||
expires_in: AccessTokenJWTExp.asSeconds(),
|
||||
profile: {
|
||||
uid: user.uid,
|
||||
email: mail ? mail.mail : "",
|
||||
name: user.name,
|
||||
enc_key: getEncryptionKey(user, client),
|
||||
},
|
||||
id_token: getIDToken(user, client.client_id, nonce),
|
||||
});
|
||||
} else if (grant_type === "refresh_token") {
|
||||
let refresh_token = req.query.refresh_token || req.body.refresh_token;
|
||||
if (!refresh_token)
|
||||
throw new RequestError(
|
||||
req.__("refresh_token not set"),
|
||||
HttpStatusCode.BAD_REQUEST
|
||||
);
|
||||
|
||||
let token = await RefreshToken.findOne({ token: refresh_token });
|
||||
if (!token || !token.valid || moment(token.validTill).isBefore())
|
||||
throw new RequestError(
|
||||
req.__("Invalid token"),
|
||||
HttpStatusCode.BAD_REQUEST
|
||||
);
|
||||
|
||||
token.validTill = moment().add(refreshTokenValidTime).toDate();
|
||||
await RefreshToken.save(token);
|
||||
|
||||
let user = await User.findById(token.user);
|
||||
let client = await Client.findById(token.client);
|
||||
let jwt = await getAccessTokenJWT({
|
||||
user,
|
||||
client,
|
||||
permissions: token.permissions,
|
||||
});
|
||||
res.json({
|
||||
access_token: jwt,
|
||||
expires_in: AccessTokenJWTExp.asSeconds(),
|
||||
});
|
||||
} else {
|
||||
throw new RequestError(
|
||||
"invalid grant_type",
|
||||
HttpStatusCode.BAD_REQUEST
|
||||
);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
export default RefreshTokenRoute;
|
||||
|
Reference in New Issue
Block a user