@loopback/authentication
Version:
A LoopBack component for authentication support.
126 lines • 5.45 kB
JavaScript
// Copyright IBM Corp. and LoopBack contributors 2019,2020. All Rights Reserved.
// Node module: @loopback/authentication
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
Object.defineProperty(exports, "__esModule", { value: true });
exports.AuthenticationMiddlewareProvider = exports.AuthenticateActionProvider = void 0;
const tslib_1 = require("tslib");
const core_1 = require("@loopback/core");
const rest_1 = require("@loopback/rest");
const security_1 = require("@loopback/security");
const keys_1 = require("../keys");
const types_1 = require("../types");
/**
* Provides the authentication action for a sequence
* @example
* ```ts
* context.bind('authentication.actions.authenticate').toProvider(AuthenticateActionProvider)
* ```
*/
let AuthenticateActionProvider = class AuthenticateActionProvider {
constructor(getStrategies, setCurrentUser, setRedirectUrl, setRedirectStatus, options = {}) {
this.getStrategies = getStrategies;
this.setCurrentUser = setCurrentUser;
this.setRedirectUrl = setRedirectUrl;
this.setRedirectStatus = setRedirectStatus;
this.options = options;
}
/**
* @returns authenticateFn
*/
value() {
return request => this.action(request);
}
/**
* The implementation of authenticate() sequence action.
* @param request - The incoming request provided by the REST layer
*/
async action(request) {
let strategies = await this.getStrategies();
if (strategies == null) {
// The invoked operation does not require authentication.
return undefined;
}
// convert to array if required
strategies = Array.isArray(strategies) ? strategies : [strategies];
const authErrors = [];
for (const strategy of strategies) {
let authResponse = undefined;
try {
authResponse = await strategy.authenticate(request);
}
catch (err) {
if (this.options.failOnError) {
throw err;
}
authErrors.push(err);
}
// response from `strategy.authenticate()` could return an object of
// type UserProfile or RedirectRoute
if (rest_1.RedirectRoute.isRedirectRoute(authResponse)) {
const redirectOptions = authResponse;
// bind redirection url and status to the context
// controller should handle actual redirection
this.setRedirectUrl(redirectOptions.targetLocation);
this.setRedirectStatus(redirectOptions.statusCode);
return;
}
else if (authResponse != null) {
// if `strategy.authenticate()` returns an object of type UserProfile,
// set it as current user
const userProfile = authResponse;
this.setCurrentUser(userProfile);
return userProfile;
}
}
if (authErrors.length) {
throw authErrors[0];
}
// important to throw a non-protocol-specific error here
const error = new Error(`User profile not returned from strategy's authenticate function`);
Object.assign(error, {
code: types_1.USER_PROFILE_NOT_FOUND,
});
throw error;
}
};
exports.AuthenticateActionProvider = AuthenticateActionProvider;
exports.AuthenticateActionProvider = AuthenticateActionProvider = tslib_1.__decorate([
tslib_1.__param(0, core_1.inject.getter(keys_1.AuthenticationBindings.STRATEGY)),
tslib_1.__param(1, core_1.inject.setter(security_1.SecurityBindings.USER)),
tslib_1.__param(2, core_1.inject.setter(keys_1.AuthenticationBindings.AUTHENTICATION_REDIRECT_URL)),
tslib_1.__param(3, core_1.inject.setter(keys_1.AuthenticationBindings.AUTHENTICATION_REDIRECT_STATUS)),
tslib_1.__param(4, (0, core_1.config)({ fromBinding: keys_1.AuthenticationBindings.COMPONENT })),
tslib_1.__metadata("design:paramtypes", [Function, Function, Function, Function, Object])
], AuthenticateActionProvider);
let AuthenticationMiddlewareProvider = class AuthenticationMiddlewareProvider {
constructor(authenticate) {
this.authenticate = authenticate;
}
value() {
return async (ctx, next) => {
try {
await this.authenticate(ctx.request);
}
catch (error) {
if (error.code === types_1.AUTHENTICATION_STRATEGY_NOT_FOUND ||
error.code === types_1.USER_PROFILE_NOT_FOUND) {
error.statusCode = 401;
}
throw error;
}
return next();
};
}
};
exports.AuthenticationMiddlewareProvider = AuthenticationMiddlewareProvider;
exports.AuthenticationMiddlewareProvider = AuthenticationMiddlewareProvider = tslib_1.__decorate([
(0, core_1.injectable)((0, rest_1.asMiddleware)({
group: rest_1.RestMiddlewareGroups.AUTHENTICATION,
upstreamGroups: [rest_1.RestMiddlewareGroups.FIND_ROUTE],
})),
tslib_1.__param(0, (0, core_1.inject)(keys_1.AuthenticationBindings.AUTH_ACTION)),
tslib_1.__metadata("design:paramtypes", [Function])
], AuthenticationMiddlewareProvider);
//# sourceMappingURL=auth-action.provider.js.map
;