diff --git a/fems-api/src/services/auth.service.js b/fems-api/src/services/auth.service.js index 73cd7e6..abc1393 100644 --- a/fems-api/src/services/auth.service.js +++ b/fems-api/src/services/auth.service.js @@ -81,113 +81,136 @@ class AuthService { } async edgeLogin(username, password, businessNumber, ipAddress, userAgent) { - // 1. 먼저 회사 검증 - const company = await Company.findOne({ - where: { + try { + // businessNumber를 숫자로 변환 + const numericBusinessNumber = parseInt( + businessNumber.replace(/[-,]/g, ""), + 10 + ); + + logger.debug("Converted business number:", { + original: businessNumber, + numeric: numericBusinessNumber, + }); + + // 1. 먼저 회사 검증 + const company = await Company.findOne({ + where: { + businessNumber, + isActive: true, + }, + }); + + if (!company) { + logger.error(`Company not found: ${businessNumber}`); + throw new Error("Invalid business number or company not found"); + } + + // 2. 사용자 검증 + const userWithPassword = await User.findOne({ + where: { + username, + companyId: company.id, + isActive: true, + }, + attributes: ["id", "password", "isActive"], + }); + + if (!userWithPassword) { + await this._logAuthAttempt( + null, + "edge_failed_login", + ipAddress, + userAgent, + businessNumber + ); + throw new Error("Invalid credentials"); + } + + // 3. 비밀번호 검증 + const isValidPassword = await userWithPassword.validatePassword(password); + if (!isValidPassword) { + await this._logAuthAttempt( + userWithPassword.id, + "edge_failed_login", + ipAddress, + userAgent, + businessNumber + ); + throw new Error("Invalid credentials"); + } + + // 4. 사용자 정보 조회 (상세 정보) + const user = await User.findOne({ + where: { id: userWithPassword.id }, + include: [ + { + model: Company, + attributes: ["id", "name", "businessNumber", "contractEndDate"], + where: { isActive: true }, // 활성화된 회사만 + }, + { + model: Branch, + attributes: ["id", "name"], + }, + { + model: Role, + through: { attributes: [] }, + attributes: ["id", "name", "permissions"], + required: false, + }, + ], + attributes: { + exclude: ["password"], + }, + }); + + // 5. 마지막 로그인 시간 업데이트 + await User.update( + { lastLoginAt: new Date() }, + { where: { id: user.id } } + ); + + // 6. 로그인 기록 + await this._logAuthAttempt( + user.id, + "edge_login", + ipAddress, + userAgent, + businessNumber + ); + + // 7. 권한 정보 처리 + const permissions = this._processPermissions(user.Roles || []); + + // 8. 응답 데이터 구성 + const userData = user.toJSON(); + const companyData = userData.Company || {}; + delete userData.Roles; + + const userInfo = { + ...userData, + companyName: companyData.name, + businessNumber: companyData.businessNumber, + contractEndDate: companyData.contractEndDate, + permissions, + isEdgeLogin: true, // Edge 로그인 여부 표시 + }; + + const token = this._generateToken(userInfo); + + return { + token, + user: userInfo, + }; + } catch (error) { + logger.error("Edge login error:", { + error: error.message, businessNumber, - isActive: true, - }, - }); - - if (!company) { - logger.error(`Company not found: ${businessNumber}`); - throw new Error("Invalid business number or company not found"); - } - - // 2. 사용자 검증 - const userWithPassword = await User.findOne({ - where: { username, - companyId: company.id, - isActive: true, - }, - attributes: ["id", "password", "isActive"], - }); - - if (!userWithPassword) { - await this._logAuthAttempt( - null, - "edge_failed_login", - ipAddress, - userAgent, - businessNumber - ); - throw new Error("Invalid credentials"); + }); + throw error; } - - // 3. 비밀번호 검증 - const isValidPassword = await userWithPassword.validatePassword(password); - if (!isValidPassword) { - await this._logAuthAttempt( - userWithPassword.id, - "edge_failed_login", - ipAddress, - userAgent, - businessNumber - ); - throw new Error("Invalid credentials"); - } - - // 4. 사용자 정보 조회 (상세 정보) - const user = await User.findOne({ - where: { id: userWithPassword.id }, - include: [ - { - model: Company, - attributes: ["id", "name", "businessNumber", "contractEndDate"], - where: { isActive: true }, // 활성화된 회사만 - }, - { - model: Branch, - attributes: ["id", "name"], - }, - { - model: Role, - through: { attributes: [] }, - attributes: ["id", "name", "permissions"], - required: false, - }, - ], - attributes: { - exclude: ["password"], - }, - }); - - // 5. 마지막 로그인 시간 업데이트 - await User.update({ lastLoginAt: new Date() }, { where: { id: user.id } }); - - // 6. 로그인 기록 - await this._logAuthAttempt( - user.id, - "edge_login", - ipAddress, - userAgent, - businessNumber - ); - - // 7. 권한 정보 처리 - const permissions = this._processPermissions(user.Roles || []); - - // 8. 응답 데이터 구성 - const userData = user.toJSON(); - const companyData = userData.Company || {}; - delete userData.Roles; - - const userInfo = { - ...userData, - companyName: companyData.name, - businessNumber: companyData.businessNumber, - contractEndDate: companyData.contractEndDate, - permissions, - isEdgeLogin: true, // Edge 로그인 여부 표시 - }; - - const token = this._generateToken(userInfo); - - return { - token, - user: userInfo, - }; } _processPermissions(roles) { diff --git a/fems-api/src/utils/createInitialAdmin.js b/fems-api/src/utils/createInitialAdmin.js index 53391eb..4fa40e6 100644 --- a/fems-api/src/utils/createInitialAdmin.js +++ b/fems-api/src/utils/createInitialAdmin.js @@ -9,41 +9,58 @@ const { const { createInitialData } = require("./initialSetup/dataSetup"); const { logCreatedAccounts } = require("./initialSetup/loggingSetup"); +// 상수로 정의하여 일관성 유지 +const ADMIN_COMPANY = { + BUSINESS_NUMBER: 4397802852, // 올바른 번호로 수정 + NAME: "FEMS 관리자", + ADDRESS: "서울시 강남구", + TEL: "02-0000-0000", + EMAIL: "admin@fems.com", + REPRESENTATIVE: "관리자", +}; + async function createInitialAdmin() { try { - // 1. 관리자 회사 생성 또는 조회 + // 사업자번호로 회사 조회 let adminCompany = await Company.findOne({ - where: { businessNumber: 4398702852 }, + where: { businessNumber: ADMIN_COMPANY.BUSINESS_NUMBER }, }); let adminBranch; // Branch 변수 선언 - const businessNumber = parseInt("439-78-02852".replace(/-/g, ""), 10); - if (!adminCompany) { + // 회사 생성 adminCompany = await Company.create({ - name: "FEMS 관리자", - businessNumber, - address: "서울시 강남구", - tel: "02-0000-0000", - email: "admin@fems.com", - representative: "관리자", + name: ADMIN_COMPANY.NAME, + businessNumber: ADMIN_COMPANY.BUSINESS_NUMBER, // 상수 사용 + address: ADMIN_COMPANY.ADDRESS, + tel: ADMIN_COMPANY.TEL, + email: ADMIN_COMPANY.EMAIL, + representative: ADMIN_COMPANY.REPRESENTATIVE, isActive: true, contractStartDate: new Date(), contractEndDate: new Date( new Date().setFullYear(new Date().getFullYear() + 10) ), }); - logger.info("Admin company created successfully"); + + logger.info("Admin company created successfully", { + companyId: adminCompany.id, + businessNumber: ADMIN_COMPANY.BUSINESS_NUMBER, + }); // 본사 지점 생성 adminBranch = await Branch.create({ name: "본사", - address: "서울시 강남구", - tel: "02-0000-0000", + address: ADMIN_COMPANY.ADDRESS, + tel: ADMIN_COMPANY.TEL, isActive: true, companyId: adminCompany.id, }); - logger.info("Admin company headquarters branch created successfully"); + + logger.info("Admin branch created successfully", { + branchId: adminBranch.id, + companyId: adminCompany.id, + }); } else { // 기존 회사의 지점 조회 adminBranch = await Branch.findOne({