@frontegg/client
Advanced tools
Comparing version 2.0.16 to 2.0.17
import { AuditsClient } from './src/audits'; | ||
import { FronteggAuthenticator } from './src/authenticator'; | ||
import { IdentityClient } from './src/identity'; | ||
import { FronteggAuthenticator } from './src/authenticator'; | ||
import { contextResolver, withAuthentication } from './src/identity'; | ||
import { frontegg, fronteggNextJs, IFronteggOptions } from './src/middleware'; | ||
import { ContextHolder, frontegg, fronteggNextJs, IFronteggOptions } from './src/middleware'; | ||
import { NotificationsClient } from './src/notifications'; | ||
@@ -12,2 +12,2 @@ import { FronteggPermissions } from './src/permissions'; | ||
export * from './src/events'; | ||
export { AuditsClient, NotificationsClient, TenantsClient, frontegg, fronteggNextJs, FronteggPermissions, IFronteggOptions, FronteggAuthenticator, RbacMiddleware, SsoClient, withAuthentication, contextResolver, IdentityClient }; | ||
export { AuditsClient, ContextHolder, NotificationsClient, TenantsClient, frontegg, fronteggNextJs, FronteggPermissions, IFronteggOptions, FronteggAuthenticator, RbacMiddleware, SsoClient, withAuthentication, contextResolver, IdentityClient, }; |
@@ -8,6 +8,6 @@ "use strict"; | ||
exports.AuditsClient = audits_1.AuditsClient; | ||
var authenticator_1 = require("./src/authenticator"); | ||
exports.FronteggAuthenticator = authenticator_1.FronteggAuthenticator; | ||
var identity_1 = require("./src/identity"); | ||
exports.IdentityClient = identity_1.IdentityClient; | ||
var authenticator_1 = require("./src/authenticator"); | ||
exports.FronteggAuthenticator = authenticator_1.FronteggAuthenticator; | ||
var identity_2 = require("./src/identity"); | ||
@@ -17,2 +17,3 @@ exports.contextResolver = identity_2.contextResolver; | ||
var middleware_1 = require("./src/middleware"); | ||
exports.ContextHolder = middleware_1.ContextHolder; | ||
exports.frontegg = middleware_1.frontegg; | ||
@@ -19,0 +20,0 @@ exports.fronteggNextJs = middleware_1.fronteggNextJs; |
@@ -6,6 +6,9 @@ export declare class FronteggAuthenticator { | ||
private apiKey; | ||
private refreshTimeout; | ||
private shuttingDown; | ||
init(clientId: string, apiKey: string): Promise<void>; | ||
refreshAuthentication(): Promise<void>; | ||
validateAuthentication(): Promise<void>; | ||
shutdown(): Promise<void>; | ||
private authenticate; | ||
} |
@@ -47,2 +47,4 @@ "use strict"; | ||
this.apiKey = ''; | ||
this.refreshTimeout = null; | ||
this.shuttingDown = false; | ||
} | ||
@@ -86,2 +88,13 @@ FronteggAuthenticator.prototype.init = function (clientId, apiKey) { | ||
}; | ||
FronteggAuthenticator.prototype.shutdown = function () { | ||
return __awaiter(this, void 0, void 0, function () { | ||
return __generator(this, function (_a) { | ||
this.shuttingDown = true; | ||
if (this.refreshTimeout !== null) { | ||
clearTimeout(this.refreshTimeout); | ||
} | ||
return [2 /*return*/]; | ||
}); | ||
}); | ||
}; | ||
FronteggAuthenticator.prototype.authenticate = function (force) { | ||
@@ -128,5 +141,7 @@ if (force === void 0) { force = false; } | ||
this.accessTokenExpiry = Date.now() + nextRefresh; | ||
setTimeout(function () { | ||
_this.refreshAuthentication(); | ||
}, nextRefresh); | ||
if (!this.shuttingDown) { | ||
this.refreshTimeout = setTimeout(function () { | ||
_this.refreshAuthentication(); | ||
}, nextRefresh); | ||
} | ||
return [2 /*return*/]; | ||
@@ -133,0 +148,0 @@ } |
@@ -5,2 +5,3 @@ "use strict"; | ||
if (exports.baseUrl.endsWith('/')) { | ||
// Take the base url | ||
exports.baseUrl = exports.baseUrl.slice(0, -1); | ||
@@ -7,0 +8,0 @@ } |
@@ -1,2 +0,2 @@ | ||
export * from './EventsClient'; | ||
export * from './types'; | ||
export * from './events'; |
@@ -6,3 +6,4 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
__export(require("./EventsClient")); | ||
__export(require("./types")); | ||
__export(require("./events")); | ||
//# sourceMappingURL=index.js.map |
@@ -1,9 +0,4 @@ | ||
export * from './WebpushProperties.interface'; | ||
export * from './BellProperties.interface'; | ||
export * from './AuditProperties.interface'; | ||
export * from './TriggerOptions.interface'; | ||
export * from './BellAction.interface'; | ||
export * from './ChannelsConfiguration.interface'; | ||
export * from './WebhookBody.type'; | ||
export * from './Channels.type'; | ||
export * from './SlackProperties.interface'; | ||
export * from './channel-configuration'; | ||
export * from './errors'; | ||
export * from './event-types'; | ||
export * from './status-types'; |
"use strict"; | ||
function __export(m) { | ||
for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; | ||
} | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
__export(require("./errors")); | ||
//# sourceMappingURL=index.js.map |
@@ -0,1 +1,2 @@ | ||
import { IUser, IWithAuthenticationOptions } from "./with-authentication"; | ||
export declare class IdentityClient { | ||
@@ -7,3 +8,4 @@ static getInstance(): IdentityClient; | ||
getPublicKey(): Promise<string>; | ||
validateIdentityOnToken(token: string, options?: IWithAuthenticationOptions): Promise<IUser>; | ||
private fetchPublicKey; | ||
} |
@@ -39,2 +39,3 @@ "use strict"; | ||
var axios_1 = require("axios"); | ||
var jsonwebtoken_1 = require("jsonwebtoken"); | ||
var authenticator_1 = require("../authenticator"); | ||
@@ -71,2 +72,82 @@ var config_1 = require("../config"); | ||
}; | ||
IdentityClient.prototype.validateIdentityOnToken = function (token, options) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
var _this = this; | ||
return __generator(this, function (_a) { | ||
return [2 /*return*/, new Promise(function (resolve, reject) { return __awaiter(_this, void 0, void 0, function () { | ||
var publicKey, e_1; | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
try { | ||
token = token.replace('Bearer ', ''); | ||
} | ||
catch (e) { | ||
logger_1.default.error('Failed to extract token - ', token); | ||
reject({ statusCode: 401, message: 'Failed to verify authentication' }); | ||
return [2 /*return*/]; | ||
} | ||
_a.label = 1; | ||
case 1: | ||
_a.trys.push([1, 3, , 4]); | ||
return [4 /*yield*/, this.getPublicKey()]; | ||
case 2: | ||
publicKey = _a.sent(); | ||
return [3 /*break*/, 4]; | ||
case 3: | ||
e_1 = _a.sent(); | ||
logger_1.default.error('failed to get public key - ', e_1); | ||
reject({ statusCode: 401, message: 'Failed to verify authentication' }); | ||
return [2 /*return*/]; | ||
case 4: | ||
jsonwebtoken_1.verify(token, publicKey, { algorithms: ['RS256'] }, function (err, decoded) { | ||
var user = decoded; | ||
if (err) { | ||
logger_1.default.error('Failed to verify jwt - ', err); | ||
reject({ statusCode: 401, message: 'Failed to verify authentication' }); | ||
return; | ||
} | ||
if (options) { | ||
var roles = options.roles, permissions = options.permissions; | ||
if (roles && roles.length > 0) { | ||
var haveAtLeastOneRole = false; | ||
for (var _i = 0, roles_1 = roles; _i < roles_1.length; _i++) { | ||
var requestedRole = roles_1[_i]; | ||
if (user.roles && user.roles.includes(requestedRole)) { | ||
haveAtLeastOneRole = true; | ||
break; | ||
} | ||
} | ||
if (!haveAtLeastOneRole) { | ||
logger_1.default.info('Insufficient role'); | ||
reject({ statusCode: 403, message: 'Insufficient role' }); | ||
return; | ||
} | ||
} | ||
if (permissions && permissions.length > 0) { | ||
var haveAtLeastOnePermission = false; | ||
for (var _a = 0, permissions_1 = permissions; _a < permissions_1.length; _a++) { | ||
var requestedPermission = permissions_1[_a]; | ||
if (user.permissions && user.permissions.includes(requestedPermission)) { | ||
haveAtLeastOnePermission = true; | ||
break; | ||
} | ||
} | ||
if (!haveAtLeastOnePermission) { | ||
logger_1.default.info('Insufficient permission'); | ||
reject({ statusCode: 403, message: 'Insufficient permission' }); | ||
return; | ||
} | ||
} | ||
} | ||
// Store the decoded user on the request | ||
resolve(user); | ||
}); | ||
return [2 /*return*/]; | ||
} | ||
}); | ||
}); })]; | ||
}); | ||
}); | ||
}; | ||
IdentityClient.prototype.fetchPublicKey = function () { | ||
@@ -97,2 +178,5 @@ return __awaiter(this, void 0, void 0, function () { | ||
this.publicKey = publicKey; | ||
return [4 /*yield*/, authenticator.shutdown()]; | ||
case 3: | ||
_b.sent(); | ||
return [2 /*return*/]; | ||
@@ -99,0 +183,0 @@ } |
@@ -38,3 +38,2 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var jsonwebtoken_1 = require("jsonwebtoken"); | ||
var identity_client_1 = require("./identity-client"); | ||
@@ -51,3 +50,3 @@ var tokenTypes; | ||
return function (req, res, next) { return __awaiter(_this, void 0, void 0, function () { | ||
var authorizationHeader, token, publicKey; | ||
var authorizationHeader, token, user, e_1, statusCode, message; | ||
return __generator(this, function (_a) { | ||
@@ -61,53 +60,28 @@ switch (_a.label) { | ||
token = authorizationHeader.replace('Bearer ', ''); | ||
return [4 /*yield*/, identity_client_1.IdentityClient.getInstance().getPublicKey()]; | ||
_a.label = 1; | ||
case 1: | ||
publicKey = _a.sent(); | ||
jsonwebtoken_1.verify(token, publicKey, { algorithms: ['RS256'] }, function (err, decoded) { | ||
var user = decoded; | ||
if (err) { | ||
res.status(401).send('Authentication failed'); | ||
return next(err); | ||
} | ||
if (roles && roles.length > 0) { | ||
var haveAtLeastOneRole = false; | ||
for (var _i = 0, roles_1 = roles; _i < roles_1.length; _i++) { | ||
var requestedRole = roles_1[_i]; | ||
if (user.roles && user.roles.includes(requestedRole)) { | ||
haveAtLeastOneRole = true; | ||
break; | ||
} | ||
} | ||
if (!haveAtLeastOneRole) { | ||
res.status(403).send('Insufficient role'); | ||
return next('Insufficient role'); | ||
} | ||
} | ||
if (permissions && permissions.length > 0) { | ||
var haveAtLeastOnePermission = false; | ||
for (var _a = 0, permissions_1 = permissions; _a < permissions_1.length; _a++) { | ||
var requestedPermission = permissions_1[_a]; | ||
if (user.permissions && user.permissions.includes(requestedPermission)) { | ||
haveAtLeastOnePermission = true; | ||
break; | ||
} | ||
} | ||
if (!haveAtLeastOnePermission) { | ||
res.status(403).send('Insufficient permission'); | ||
return next('Insufficient permission'); | ||
} | ||
} | ||
// Store the decoded user on the request | ||
req.user = user; | ||
req.user.id = ''; | ||
switch (req.user.type) { | ||
case tokenTypes.UserToken: | ||
req.user.id = user.sub; // The subject of the token (OpenID token) is saved on the req.user as well for easier readability | ||
break; | ||
case tokenTypes.UserApiToken: | ||
req.user.id = user.createdByUserId; | ||
break; | ||
} | ||
// And move to the next handler | ||
next(); | ||
}); | ||
_a.trys.push([1, 3, , 4]); | ||
return [4 /*yield*/, identity_client_1.IdentityClient.getInstance().validateIdentityOnToken(token, { roles: roles, permissions: permissions })]; | ||
case 2: | ||
user = _a.sent(); | ||
return [3 /*break*/, 4]; | ||
case 3: | ||
e_1 = _a.sent(); | ||
statusCode = e_1.statusCode, message = e_1.message; | ||
res.status(statusCode).send(message); | ||
return [2 /*return*/, next(e_1)]; | ||
case 4: | ||
// Store the decoded user on the request | ||
req.user = user; | ||
req.user.id = ''; | ||
switch (req.user.type) { | ||
case tokenTypes.UserToken: | ||
req.user.id = user.sub; // The subject of the token (OpenID token) is saved on the req.user as well for easier readability | ||
break; | ||
case tokenTypes.UserApiToken: | ||
req.user.id = user.createdByUserId; | ||
break; | ||
} | ||
// And move to the next handler | ||
next(); | ||
return [2 /*return*/]; | ||
@@ -114,0 +88,0 @@ } |
@@ -45,8 +45,7 @@ "use strict"; | ||
var utils_1 = require("./utils"); | ||
var proxy = httpProxy.createProxyServer({ secure: false, changeOrigin: true }); | ||
var proxy = httpProxy.createProxyServer({ secure: false, changeOrigin: true, xfwd: true }); | ||
var target = process.env.FRONTEGG_API_GATEWAY_URL || 'https://api.frontegg.com/'; | ||
var pjson = getPackageJSON_1.getPackageJson() || { version: 'unknown' }; | ||
var authenticator = new authenticator_1.FronteggAuthenticator(); | ||
var MAX_RETRIES = 3; | ||
function proxyRequest(req, res, context) { | ||
function proxyRequest(req, res, context, authenticator) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
@@ -97,2 +96,3 @@ var headers; | ||
} | ||
var authenticator = new authenticator_1.FronteggAuthenticator(); | ||
ContextHolder_1.ContextHolder.setContext({ | ||
@@ -118,3 +118,3 @@ FRONTEGG_CLIENT_ID: options.clientId, | ||
context = _a.sent(); | ||
return [2 /*return*/, proxyRequest(req, res, context)]; | ||
return [2 /*return*/, proxyRequest(req, res, context, authenticator)]; | ||
} | ||
@@ -190,2 +190,3 @@ }); | ||
// response was already sent from the middleware, we have nothing left to do | ||
logger_1.default.debug('Headers was already sent from authMiddleware'); | ||
return [2 /*return*/]; | ||
@@ -197,2 +198,7 @@ } | ||
logger_1.default.error("Failed to call middleware - ", e_1); | ||
if (res.headersSent) { | ||
// response was already sent from the middleware, we have nothing left to do | ||
logger_1.default.debug('authMiddleware threw error, but headers was already sent'); | ||
return [2 /*return*/]; | ||
} | ||
return [2 /*return*/, res.status(401).send(e_1.message)]; | ||
@@ -229,3 +235,3 @@ case 7: | ||
logger_1.default.debug("going to proxy request"); | ||
return [2 /*return*/, proxyRequest(req, res, context)]; | ||
return [2 /*return*/, proxyRequest(req, res, context, authenticator)]; | ||
} | ||
@@ -232,0 +238,0 @@ }); |
{ | ||
"name": "@frontegg/client", | ||
"version": "2.0.16", | ||
"version": "2.0.17", | ||
"description": "Frontegg Javascript Library for backend", | ||
@@ -5,0 +5,0 @@ "main": "dist/index.js", |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
241852
103
3539