n8n
Version:
n8n Workflow Automation Tool
225 lines • 10.7 kB
JavaScript
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
var __param = (this && this.__param) || function (paramIndex, decorator) {
return function (target, key) { decorator(target, key, paramIndex); }
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.AuthController = void 0;
const api_types_1 = require("@n8n/api-types");
const backend_common_1 = require("@n8n/backend-common");
const db_1 = require("@n8n/db");
const decorators_1 = require("@n8n/decorators");
const di_1 = require("@n8n/di");
const class_validator_1 = require("class-validator");
const auth_1 = require("../auth");
const auth_service_1 = require("../auth/auth.service");
const constants_1 = require("../constants");
const auth_error_1 = require("../errors/response-errors/auth.error");
const bad_request_error_1 = require("../errors/response-errors/bad-request.error");
const forbidden_error_1 = require("../errors/response-errors/forbidden.error");
const event_service_1 = require("../events/event.service");
const license_1 = require("../license");
const mfa_service_1 = require("../mfa/mfa.service");
const posthog_1 = require("../posthog");
const user_service_1 = require("../services/user.service");
const sso_helpers_1 = require("../sso.ee/sso-helpers");
let AuthController = class AuthController {
constructor(logger, authService, mfaService, userService, license, userRepository, eventService, postHog) {
this.logger = logger;
this.authService = authService;
this.mfaService = mfaService;
this.userService = userService;
this.license = license;
this.userRepository = userRepository;
this.eventService = eventService;
this.postHog = postHog;
}
async login(req, res, payload) {
const { emailOrLdapLoginId, password, mfaCode, mfaRecoveryCode } = payload;
let user;
let usedAuthenticationMethod = (0, sso_helpers_1.getCurrentAuthenticationMethod)();
if (usedAuthenticationMethod === 'email' && !(0, class_validator_1.isEmail)(emailOrLdapLoginId)) {
throw new bad_request_error_1.BadRequestError('Invalid email address');
}
if ((0, sso_helpers_1.isSamlCurrentAuthenticationMethod)()) {
const preliminaryUser = await (0, auth_1.handleEmailLogin)(emailOrLdapLoginId, password);
if (preliminaryUser?.role === 'global:owner' ||
preliminaryUser?.settings?.allowSSOManualLogin) {
user = preliminaryUser;
usedAuthenticationMethod = 'email';
}
else {
throw new auth_error_1.AuthError('SSO is enabled, please log in with SSO');
}
}
else if ((0, sso_helpers_1.isLdapCurrentAuthenticationMethod)()) {
const preliminaryUser = await (0, auth_1.handleEmailLogin)(emailOrLdapLoginId, password);
if (preliminaryUser?.role === 'global:owner') {
user = preliminaryUser;
usedAuthenticationMethod = 'email';
}
else {
const { LdapService } = await Promise.resolve().then(() => __importStar(require('../ldap.ee/ldap.service.ee')));
user = await di_1.Container.get(LdapService).handleLdapLogin(emailOrLdapLoginId, password);
}
}
else {
user = await (0, auth_1.handleEmailLogin)(emailOrLdapLoginId, password);
}
if (user) {
if (user.mfaEnabled) {
if (!mfaCode && !mfaRecoveryCode) {
throw new auth_error_1.AuthError('MFA Error', 998);
}
const isMfaCodeOrMfaRecoveryCodeValid = await this.mfaService.validateMfa(user.id, mfaCode, mfaRecoveryCode);
if (!isMfaCodeOrMfaRecoveryCodeValid) {
throw new auth_error_1.AuthError('Invalid mfa token or recovery code');
}
}
this.authService.issueCookie(res, user, user.mfaEnabled, req.browserId);
this.eventService.emit('user-logged-in', {
user,
authenticationMethod: usedAuthenticationMethod,
});
return await this.userService.toPublic(user, {
posthog: this.postHog,
withScopes: true,
mfaAuthenticated: user.mfaEnabled,
});
}
this.eventService.emit('user-login-failed', {
authenticationMethod: usedAuthenticationMethod,
userEmail: emailOrLdapLoginId,
reason: 'wrong credentials',
});
throw new auth_error_1.AuthError('Wrong username or password. Do you have caps lock on?');
}
async currentUser(req) {
return await this.userService.toPublic(req.user, {
posthog: this.postHog,
withScopes: true,
mfaAuthenticated: req.authInfo?.usedMfa,
});
}
async resolveSignupToken(_req, _res, payload) {
const { inviterId, inviteeId } = payload;
const isWithinUsersLimit = this.license.isWithinUsersLimit();
if (!isWithinUsersLimit) {
this.logger.debug('Request to resolve signup token failed because of users quota reached', {
inviterId,
inviteeId,
});
throw new forbidden_error_1.ForbiddenError(constants_1.RESPONSE_ERROR_MESSAGES.USERS_QUOTA_REACHED);
}
const users = await this.userRepository.findManyByIds([inviterId, inviteeId]);
if (users.length !== 2) {
this.logger.debug('Request to resolve signup token failed because the ID of the inviter and/or the ID of the invitee were not found in database', { inviterId, inviteeId });
throw new bad_request_error_1.BadRequestError('Invalid invite URL');
}
const invitee = users.find((user) => user.id === inviteeId);
if (!invitee || invitee.password) {
this.logger.error('Invalid invite URL - invitee already setup', {
inviterId,
inviteeId,
});
throw new bad_request_error_1.BadRequestError('The invitation was likely either deleted or already claimed');
}
const inviter = users.find((user) => user.id === inviterId);
if (!inviter?.email || !inviter?.firstName) {
this.logger.error('Request to resolve signup token failed because inviter does not exist or is not set up', {
inviterId: inviter?.id,
});
throw new bad_request_error_1.BadRequestError('Invalid request');
}
this.eventService.emit('user-invite-email-click', { inviter, invitee });
const { firstName, lastName } = inviter;
return { inviter: { firstName, lastName } };
}
async logout(req, res) {
await this.authService.invalidateToken(req);
this.authService.clearCookie(res);
return { loggedOut: true };
}
};
exports.AuthController = AuthController;
__decorate([
(0, decorators_1.Post)('/login', { skipAuth: true, rateLimit: true }),
__param(2, decorators_1.Body),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Object, Object, api_types_1.LoginRequestDto]),
__metadata("design:returntype", Promise)
], AuthController.prototype, "login", null);
__decorate([
(0, decorators_1.Get)('/login', {
allowSkipMFA: true,
}),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Object]),
__metadata("design:returntype", Promise)
], AuthController.prototype, "currentUser", null);
__decorate([
(0, decorators_1.Get)('/resolve-signup-token', { skipAuth: true }),
__param(2, decorators_1.Query),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Object, Object, api_types_1.ResolveSignupTokenQueryDto]),
__metadata("design:returntype", Promise)
], AuthController.prototype, "resolveSignupToken", null);
__decorate([
(0, decorators_1.Post)('/logout'),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Object, Object]),
__metadata("design:returntype", Promise)
], AuthController.prototype, "logout", null);
exports.AuthController = AuthController = __decorate([
(0, decorators_1.RestController)(),
__metadata("design:paramtypes", [backend_common_1.Logger,
auth_service_1.AuthService,
mfa_service_1.MfaService,
user_service_1.UserService,
license_1.License,
db_1.UserRepository,
event_service_1.EventService,
posthog_1.PostHogClient])
], AuthController);
//# sourceMappingURL=auth.controller.js.map
;