From d70c457d10e614205fa9962450833b565c2721d2 Mon Sep 17 00:00:00 2001 From: comicgum Date: Thu, 17 Sep 2026 15:44:25 +0900 Subject: [PATCH] =?UTF-8?q?=EA=B3=84=EC=A0=95=20=EB=B0=9C=EA=B8=89,=20?= =?UTF-8?q?=EC=88=98=EC=A0=95=20=EC=9E=84=EC=8B=9C=EB=B9=84=EB=B0=80?= =?UTF-8?q?=EB=B2=88=ED=98=B8=20=EB=A1=9C=EC=A7=81=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- smartservice_backend/Dockerfile | 8 +- smartservice_backend/docker-compose.yaml | 12 +-- .../controller/api/AccountController.java | 3 +- .../smartservice/mapper/AccountMapper.java | 2 + .../smartservice/mapper/BizGroupMapper.java | 2 + .../smartservice/service/AccountService.java | 90 +++++++++++++++--- .../smartservice/service/BizGroupService.java | 17 +--- .../main/resources/mapper/AccountMapper.xml | 8 ++ .../main/resources/mapper/BizGroupMapper.xml | 7 ++ .../(admin)/account/AddModifyAccountModal.tsx | 95 +++++++++++++++---- .../AddModifyCustomerAccountModal.tsx | 93 ++++++++++++++---- .../src/components/ResetPasswordModal.tsx | 65 ------------- .../src/lib/resetAccountPassword.ts | 28 ++++++ 13 files changed, 289 insertions(+), 141 deletions(-) delete mode 100644 smartservice_frontend/src/components/ResetPasswordModal.tsx create mode 100644 smartservice_frontend/src/lib/resetAccountPassword.ts diff --git a/smartservice_backend/Dockerfile b/smartservice_backend/Dockerfile index 5b92a23..6740955 100644 --- a/smartservice_backend/Dockerfile +++ b/smartservice_backend/Dockerfile @@ -1,8 +1,8 @@ -# docker build -t hd1-was:1.0.8 . -# docker tag hd1-was:1.0.8 192.168.219.191:19101/hd1-was:1.0.8 -# docker push 192.168.219.191:19101/hd1-was:1.0.8 +# docker build -t hd1-was:1.1.0 . +# docker tag hd1-was:1.1.0 192.168.219.191:19101/hd1-was:1.1.0 +# docker push 192.168.219.191:19101/hd1-was:1.1.0 # or -# .\_docker_push.bat 1.0.8 +# .\_docker_push.bat 1.1.0 FROM eclipse-temurin:21-jdk WORKDIR /app diff --git a/smartservice_backend/docker-compose.yaml b/smartservice_backend/docker-compose.yaml index d02add2..f3cd0c9 100644 --- a/smartservice_backend/docker-compose.yaml +++ b/smartservice_backend/docker-compose.yaml @@ -1,13 +1,13 @@ -# docker pull 49.165.181.28:19101/hd1-was:1.0.8 -docker stop hd1-was -docker rm hd1-was -docker-compose up -d +# docker pull 49.165.181.28:19101/hd1-was:1.1.0 +# docker stop hd1-was +# docker rm hd1-was +# docker-compose up -d # or -# _docker_pull_restart.sh 1.0.8 +# _docker_pull_restart.sh 1.1.0 services: hd1: - image: 49.165.181.28:19101/hd1-was:1.0.8 + image: 49.165.181.28:19101/hd1-was:1.1.0 container_name: hd1-was ports: - "28080:18080" diff --git a/smartservice_backend/src/main/java/com/handong/smartservice/controller/api/AccountController.java b/smartservice_backend/src/main/java/com/handong/smartservice/controller/api/AccountController.java index 6e23d09..b9b0a22 100644 --- a/smartservice_backend/src/main/java/com/handong/smartservice/controller/api/AccountController.java +++ b/smartservice_backend/src/main/java/com/handong/smartservice/controller/api/AccountController.java @@ -104,7 +104,8 @@ class AccountController { Boolean perm_uid1 = _AG.toBoolean(body.get("perm_uid1")); Boolean perm_cancel = _AG.toBoolean(body.get("perm_cancel")); - if (user_id == null || user_id.isEmpty()) { + // A new account is issued with the business number as its ID, so only a modification names one + if (isModify && (user_id == null || user_id.isEmpty())) { result.setErrCode(ErrorCode.INVALID_PARAMETER); return result; } diff --git a/smartservice_backend/src/main/java/com/handong/smartservice/mapper/AccountMapper.java b/smartservice_backend/src/main/java/com/handong/smartservice/mapper/AccountMapper.java index 85f4523..968a592 100644 --- a/smartservice_backend/src/main/java/com/handong/smartservice/mapper/AccountMapper.java +++ b/smartservice_backend/src/main/java/com/handong/smartservice/mapper/AccountMapper.java @@ -26,4 +26,6 @@ public interface AccountMapper { int updateInitAccount(Long gid, String user_id, String user_pw); int updateResetPassword(Long gid, String user_pw); + + int invalidatePendingIssuedAccount(String user_id); } diff --git a/smartservice_backend/src/main/java/com/handong/smartservice/mapper/BizGroupMapper.java b/smartservice_backend/src/main/java/com/handong/smartservice/mapper/BizGroupMapper.java index b011c1c..899dce0 100644 --- a/smartservice_backend/src/main/java/com/handong/smartservice/mapper/BizGroupMapper.java +++ b/smartservice_backend/src/main/java/com/handong/smartservice/mapper/BizGroupMapper.java @@ -14,6 +14,8 @@ public interface BizGroupMapper { String phone, String address); Map selectExistBizGroup(Long biz_group_id, String biz_reg_num); + + String selectBizRegNumById(Long biz_group_id); Map selectBizGroupByDeviceId(Long device_id); Map selectBizGroupByTerminalId(Long terminal_id); diff --git a/smartservice_backend/src/main/java/com/handong/smartservice/service/AccountService.java b/smartservice_backend/src/main/java/com/handong/smartservice/service/AccountService.java index 0a7a8dc..3eb7024 100644 --- a/smartservice_backend/src/main/java/com/handong/smartservice/service/AccountService.java +++ b/smartservice_backend/src/main/java/com/handong/smartservice/service/AccountService.java @@ -23,8 +23,11 @@ import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.transaction.interceptor.TransactionAspectSupport; import com.handong.smartservice.mapper.AccountMapper; +import com.handong.smartservice.mapper.BizGroupMapper; @Service @@ -34,14 +37,16 @@ public class AccountService { private final AccountMapper accountMapper; private final PasswordEncoder passwordEncoder; private final SMSSender smsSender; + private final BizGroupMapper bizGroupMapper; @Value("${sms.callback}") String smsCallback; @Value("${account.site-url}") String siteUrl; - public AccountService(AccountMapper accountMapper, PasswordEncoder passwordEncoder, SMSSender smsSender) { + public AccountService(AccountMapper accountMapper, PasswordEncoder passwordEncoder, SMSSender smsSender, BizGroupMapper bizGroupMapper) { this.accountMapper = accountMapper; this.passwordEncoder = passwordEncoder; this.smsSender = smsSender; + this.bizGroupMapper = bizGroupMapper; } public CtResponse getAccount(Long gid, String user_id) { @@ -78,6 +83,7 @@ public class AccountService { return mapResult; } + @Transactional public CtResponse addOrModifyAccount(boolean isModify, Long gid, String user_id, String user_pw, String email, String name, String phone,Long state, Long biz_group_id, Long new_biz_group_id, Boolean perm_group, Boolean perm_uid1, Boolean perm_cancel) { CtResponse result = new CtResponse(); @@ -85,7 +91,8 @@ public class AccountService { //UserInfo userInfo = (UserInfo)SecurityContextHolder.getContext().getAuthentication().getPrincipal(); UserInfo userInfo = UserInfo.getCurr(); - String enc_pw = passwordEncoder.encode(user_pw); + // A modification without a password (someone else's account) keeps the stored one + String enc_pw = user_pw == null || user_pw.isEmpty() ? null : passwordEncoder.encode(user_pw); if (new_biz_group_id != 0 && new_biz_group_id != biz_group_id) biz_group_id = new_biz_group_id; @@ -107,19 +114,33 @@ public class AccountService { DbLogger.insert(2L, "계정정보 수정", userInfo.getGid()); } else { + // A new account is issued like the one of a new business group: the ID is the group's business number, + // a temporary password is texted to the mobile number, and the user picks their own ID and password at the first sign in + String mobile = phone == null ? "" : phone.replaceAll("[^0-9]", ""); + user_id = biz_group_id == 0 ? null : bizGroupMapper.selectBizRegNumById(biz_group_id); if (user_id == null || user_id.isEmpty()) { - result.setErrCode(ErrorCode.INVALID_PARAMETER); + result.setErrCode(ErrorCode.INVALID_BIZ_REG_NUM); + return result; + } + if (mobile.matches("^01[016789][0-9]{7,8}$") == false) { + result.setErrCode(ErrorCode.INVALID_MOBILE); + return result; + } + invalidatePendingIssuedAccount(user_id); + if (accountMapper.countActiveUserId(user_id, 0L) > 0) { + result.setErrCode(ErrorCode.ACCOUNT_ALREADY_EXIST); return result; } + String tempPw = TempPassword.create(); + Map params = new HashMap<>(); params.put("user_id", user_id); - //params.put("user_pw", user_pw); - params.put("user_pw", enc_pw); + params.put("user_pw", passwordEncoder.encode(tempPw)); params.put("name", name); - params.put("phone", phone); + params.put("phone", mobile); params.put("email", email); - params.put("state", state); + params.put("state", BizGroupService.ACCOUNT_STATE_INIT); params.put("biz_group_id", biz_group_id); if (biz_group_id == 667) //TempCode @@ -134,19 +155,58 @@ public class AccountService { if (accountMapper.insertAccount(params) == 0) { result.setErrCode(ErrorCode.INVALID_PARAMETER); + return result; } - else { - DbLogger.insert(2L, "신규 계정 추가, id: " + user_id, userInfo.getGid()); - //result.put("result", Map.of("gid", params.get("gid"))); - Map ret = new HashMap(); - ret.put("gid", params.get("gid")); - result.put("result", ret); + + // A failed message rolls the account back, so the registration can simply be retried + String smsCode = sendIssuedAccountMessage(user_id, tempPw, mobile); + if (smsCode != null) { + TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); + result.setErrCode(ErrorCode.SMS_SEND_FAILED); + result.put("sms_code", smsCode); + return result; } + + DbLogger.insert(2L, "신규 계정 추가(계정발급), id: " + user_id, userInfo.getGid()); + //result.put("result", Map.of("gid", params.get("gid"))); + Map ret = new HashMap(); + ret.put("gid", params.get("gid")); + result.put("result", ret); } return result; } + /** + * Terminates the earlier issued accounts of a business number that still wait for their first sign in, + * so the account issued next is the only one whose temporary password works. Runs inside the caller's + * transaction: a failed issue (e.g. the text message) restores them. + */ + public void invalidatePendingIssuedAccount(String user_id) { + int changed = accountMapper.invalidatePendingIssuedAccount(user_id); + if (changed > 0) + logger.info("invalidatePendingIssuedAccount: user_id={}, invalidated={}", user_id, changed); + } + + /** + * Texts the sign in information of a newly issued account. + * + * @return null when the message was sent, otherwise the gateway result code + */ + public String sendIssuedAccountMessage(String user_id, String tempPw, String mobile) { + String msg = "[스마트서비스] 계정이 발급되었습니다.\n" + + "사이트: " + siteUrl + "\n" + + "ID: " + user_id + "\n" + + "임시비밀번호: " + tempPw + "\n" + + "로그인 후 아이디와 비밀번호를 변경해 주세요."; + + SMSSender.Result sendResult = smsSender.send(smsCallback, mobile, msg); + if (sendResult.isSuccess() == false) + logger.warn("sendIssuedAccountMessage: sms failed, user_id={}, mobile={}, result={}", user_id, mobile, sendResult); + + return sendResult.isSuccess() ? null : sendResult.code; + } + /** * Replaces the temporary ID and password of an issued account (state 6) with the user's own. * The temporary credentials are checked again here, because the caller has no token yet. @@ -203,6 +263,7 @@ public class AccountService { String mobile = phone == null ? "" : phone.replaceAll("[^0-9]", ""); if (gid == 0 || mobile.matches("^01[016789][0-9]{7,8}$") == false) { + logger.info("resetPassword: bad parameter, gid={}, mobile={}", gid, mobile); result.setErrCode(ErrorCode.INVALID_MOBILE); return result; } @@ -210,12 +271,14 @@ public class AccountService { CtResponse resAccount = getAccount(gid, null); Map mapAccount = (Map)resAccount.get("result"); if (mapAccount == null) { + logger.info("resetPassword: account not found, gid={}", gid); result.setErrCode(ErrorCode.INVALID_USER); return result; } String newPw = TempPassword.create(); if (accountMapper.updateResetPassword(gid, passwordEncoder.encode(newPw)) == 0) { + logger.info("resetPassword: nothing updated, gid={}", gid); result.setErrCode(ErrorCode.QUERY_ERROR); return result; } @@ -228,6 +291,7 @@ public class AccountService { SMSSender.Result sendResult = smsSender.send(smsCallback, mobile, msg); if (sendResult.isSuccess() == false) { + logger.warn("resetPassword: sms failed, gid={}, mobile={}, result={}", gid, mobile, sendResult); result.setErrCode(ErrorCode.SMS_SEND_FAILED); result.put("sms_code", sendResult.code); return result; diff --git a/smartservice_backend/src/main/java/com/handong/smartservice/service/BizGroupService.java b/smartservice_backend/src/main/java/com/handong/smartservice/service/BizGroupService.java index 0d7563f..329a1a6 100644 --- a/smartservice_backend/src/main/java/com/handong/smartservice/service/BizGroupService.java +++ b/smartservice_backend/src/main/java/com/handong/smartservice/service/BizGroupService.java @@ -13,7 +13,6 @@ import org.apache.ibatis.jdbc.SQL; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -25,7 +24,6 @@ import com.handong.smartservice.component.DbLogger; import com.handong.smartservice.component.ErrorCode; import com.handong.smartservice.component.Permission; import com.handong.smartservice.component.RcTreeBizGroup; -import com.handong.smartservice.component.SMSSender; import com.handong.smartservice.component.TempPassword; import com.handong.smartservice.component.UserInfo; import com.handong.smartservice.mapper.AccountMapper; @@ -43,10 +41,7 @@ public class BizGroupService { @Autowired BizGroupMapper bizGroupMapper; @Autowired AccountMapper accountMapper; @Autowired PasswordEncoder passwordEncoder; - @Autowired SMSSender smsSender; - - @Value("${sms.callback}") String smsCallback; - @Value("${account.site-url}") String siteUrl; + @Autowired AccountService accountService; public Map getBizGroupList(Long offset, Long limit, String date_start, String date_end, @@ -98,6 +93,7 @@ public class BizGroupService { result.setErrCode(ErrorCode.INVALID_MOBILE); return result; } + accountService.invalidatePendingIssuedAccount(biz_reg_num); if (accountMapper.countActiveUserId(biz_reg_num, 0L) > 0) { result.setErrCode(ErrorCode.ACCOUNT_ALREADY_EXIST); return result; @@ -179,14 +175,7 @@ public class BizGroupService { params.put("permission", permission.get()); accountMapper.insertAccount(params); - String msg = "[스마트서비스] 계정이 발급되었습니다.\n" - + "사이트: " + siteUrl + "\n" - + "ID: " + biz_reg_num + "\n" - + "임시비밀번호: " + tempPw + "\n" - + "로그인 후 아이디와 비밀번호를 변경해 주세요."; - - SMSSender.Result sendResult = smsSender.send(smsCallback, mobile, msg); - return sendResult.isSuccess() ? null : sendResult.code; + return accountService.sendIssuedAccountMessage(biz_reg_num, tempPw, mobile); } diff --git a/smartservice_backend/src/main/resources/mapper/AccountMapper.xml b/smartservice_backend/src/main/resources/mapper/AccountMapper.xml index e1396d7..535d406 100644 --- a/smartservice_backend/src/main/resources/mapper/AccountMapper.xml +++ b/smartservice_backend/src/main/resources/mapper/AccountMapper.xml @@ -163,6 +163,14 @@ WHERE gid = #{gid} AND state != 2 + + + UPDATE account + SET state = 2 + WHERE user_id = #{user_id} AND state = 6 + + UPDATE account diff --git a/smartservice_backend/src/main/resources/mapper/BizGroupMapper.xml b/smartservice_backend/src/main/resources/mapper/BizGroupMapper.xml index f5a95ac..3acc413 100644 --- a/smartservice_backend/src/main/resources/mapper/BizGroupMapper.xml +++ b/smartservice_backend/src/main/resources/mapper/BizGroupMapper.xml @@ -41,6 +41,13 @@ + + + multiState.set("user_id", e.target.value)} disabled={multiState.values.isModify ? true : false} /> + {/* A new account signs in with the business number and picks its own ID at the first sign in */} + { multiState.values.isModify ? + + : + + } + + { showPassword && <> + { isSelf && +
+ +
+ } +
+ + multiState.set("user_pw", e.target.value)} disabled={!needPassword} />
- - multiState.set("user_pw", e.target.value)} /> -
-
- - setUserPwConfirm(e.target.value)} /> + + setUserPwConfirm(e.target.value)} disabled={!needPassword} />
+ }
multiState.set("name", e.target.value)} /> @@ -156,6 +210,8 @@ export default function AddModifyAccountModal({ multiState, onOk, isOpen, closeM
+ {/* A new account always starts initialized: the server sets it */} + { multiState.values.isModify ? + }
- { multiState.values.isModify && + { multiState.values.isModify && !isSelf &&
- - +
} - // ); diff --git a/smartservice_frontend/src/app/(admin)/customer-account/AddModifyCustomerAccountModal.tsx b/smartservice_frontend/src/app/(admin)/customer-account/AddModifyCustomerAccountModal.tsx index c4fb26f..a353983 100644 --- a/smartservice_frontend/src/app/(admin)/customer-account/AddModifyCustomerAccountModal.tsx +++ b/smartservice_frontend/src/app/(admin)/customer-account/AddModifyCustomerAccountModal.tsx @@ -1,14 +1,13 @@ "use client"; import React, { useState, useRef, useEffect } from "react"; import CtModal from "@/components/CtModal"; -import ResetPasswordModal from "@/components/ResetPasswordModal"; import Button from "@/components/ui/button/Button2"; -import { useModal } from "@/hooks/useModal"; import Label from '@/components/form/Label2'; import Input from '@/components/form/input/InputField2'; import Select from '@/components/form/Select2'; import { useMultiState } from "@/hooks/useMultiState"; import api, { useAuthStore } from '@/lib/_AG'; +import { resetAccountPassword } from '@/lib/resetAccountPassword'; import Checkbox from "@/components/form/input/Checkbox"; @@ -46,23 +45,50 @@ export default function AddModifyCustomerAccountModal({ multiState, onOk, isOpen const [ user_pw_confirm, setUserPwConfirm ] = useState(""); - const { isOpen: isOpenReset, openModal: openResetModal, closeModal: closeResetModal } = useModal(); + // Only the signed-in user changes their own password here; anyone else's password is reset by text message + const isSelf = multiState.values.isModify && tokenPayload?.user_id === multiState.values.user_id; + // A new account gets a temporary password by text message, like an account issued with a business group + const showPassword = isSelf; + + // Modifying yourself keeps the password unless the change box is checked + const [ isChangePw, setIsChangePw ] = useState(false); + const needPassword = isSelf && isChangePw; + + // Every opening starts with the box cleared and nothing typed + useEffect(() => { + if (isOpen) { + setIsChangePw(false); + setUserPwConfirm(""); + } + }, [isOpen]); + + const handleChangeIsChangePw = (checked: boolean) => { + setIsChangePw(checked); + if (!checked) { + multiState.set("user_pw", ""); + setUserPwConfirm(""); + } + }; const handleClickAddOrModify = () => { - if (multiState.values.user_id == "") { + if (multiState.values.isModify && multiState.values.user_id == "") { alert("계정 아이디를 입력하셔야 합니다."); return; } - else if (multiState.values.user_pw == "") { + else if (!multiState.values.isModify && !multiState.values.biz_reg_num) { + alert("사업자번호가 등록된 사업자만 계정을 발급할 수 있습니다."); + return; + } + else if (needPassword && multiState.values.user_pw == "") { alert("계정 비밀번호를 입력하셔야 합니다."); return; } - else if (user_pw_confirm == "") { + else if (needPassword && user_pw_confirm == "") { alert("비밀번호 확인을 입력하셔야 합니다."); return; } - else if (multiState.values.user_pw !== user_pw_confirm) { + else if (needPassword && multiState.values.user_pw !== user_pw_confirm) { alert("비밀번호 확인이 일치하지 않습니다."); return; } @@ -74,6 +100,10 @@ export default function AddModifyCustomerAccountModal({ multiState, onOk, isOpen alert("휴대폰 번호를 입력하셔야 합니다."); return; } + else if (!multiState.values.isModify && !/^01[016789][0-9]{7,8}$/.test(multiState.values.phone.replace(/[^0-9]/g, ""))) { + alert("임시 비밀번호를 문자로 보내려면 올바른 휴대폰 번호를 입력해야 합니다."); + return; + } const { biz_group_name, biz_reg_num, ...params } = multiState.values; @@ -96,9 +126,21 @@ export default function AddModifyCustomerAccountModal({ multiState, onOk, isOpen console.log(resp); if (resp.data.errCode == 0) { - alert("추가되었습니다."); + alert("추가되었습니다. 발급된 계정 정보를 휴대폰으로 보냈습니다."); onOk(); } + else if (resp.data.errCode == -19) { + alert("임시 비밀번호를 문자로 보내려면 올바른 휴대폰 번호를 입력해야 합니다."); + } + else if (resp.data.errCode == -20) { + alert("문자 발송에 실패해 계정 등록이 취소되었습니다. 잠시 후 다시 시도하세요."); + } + else if (resp.data.errCode == -17) { + alert("사업자번호가 등록된 사업자만 계정을 발급할 수 있습니다."); + } + else if (resp.data.errCode == -21) { + alert("이 사업자번호를 아이디로 사용 중인 계정이 이미 있습니다."); + } else { alert("일시적으로 사용할 수 없습니다 : " + resp.data.errCode); } @@ -126,18 +168,28 @@ export default function AddModifyCustomerAccountModal({ multiState, onOk, isOpen
- multiState.set("user_id", e.target.value)} disabled={multiState.values.isModify ? true : false} /> + {/* A new account signs in with the business number and picks its own ID at the first sign in */} + { multiState.values.isModify ? + + : + + }
- { !multiState.values.isModify || (multiState.values.isModify && tokenPayload?.user_id === multiState.values.user_id) ? <> + { showPassword && <> + { isSelf &&
- - multiState.set("user_pw", e.target.value)} /> + +
+ } +
+ + multiState.set("user_pw", e.target.value)} disabled={!needPassword} />
- - setUserPwConfirm(e.target.value)} /> + + setUserPwConfirm(e.target.value)} disabled={!needPassword} />
- : <>} + }
multiState.set("name", e.target.value)} /> @@ -161,6 +213,8 @@ export default function AddModifyCustomerAccountModal({ multiState, onOk, isOpen
+ {/* A new account always starts initialized: the server sets it */} + { multiState.values.isModify ? + }
- { multiState.values.isModify && + { multiState.values.isModify && !isSelf &&
- - +
} - // ); diff --git a/smartservice_frontend/src/components/ResetPasswordModal.tsx b/smartservice_frontend/src/components/ResetPasswordModal.tsx deleted file mode 100644 index 0a55ecd..0000000 --- a/smartservice_frontend/src/components/ResetPasswordModal.tsx +++ /dev/null @@ -1,65 +0,0 @@ -"use client"; -import React, { useEffect, useState } from "react"; -import CtModal from "@/components/CtModal"; -import Label from '@/components/form/Label2'; -import Input from '@/components/form/input/InputField2'; -import api from '@/lib/_AG'; - - -interface ResetPasswordModalProps { - gid: string; - phone: string; // the account's mobile number, shown as the default - isOpen: boolean; - closeModal: () => void; -} - -/** Sends a new temporary password to the account holder's mobile number */ -export default function ResetPasswordModal({ gid, phone, isOpen, closeModal }: ResetPasswordModalProps) { - const [ inputPhone, setInputPhone ] = useState(""); - - useEffect(() => { - if (isOpen) - setInputPhone(phone ?? ""); - }, [isOpen, phone]); - - const handleClickSend = () => { - if (inputPhone.trim() == "") { - alert("휴대폰 번호를 입력하세요"); - return; - } - - api.post('/api/reset-account-password.do', { gid: gid, phone: inputPhone }).then((resp) => { - if (resp.data.errCode == 0) { - alert("임시 비밀번호 전송완료"); - closeModal(); - } - else { - alert("전송에 실패했습니다."); - } - }) - .catch((err) => { - console.error(err); - alert("전송에 실패했습니다."); - }); - }; - - return ( - -
- {"비밀번호 초기화는 사용자의 휴대폰에 임시 비밀번호를 문자로 전송합니다.\n사용자의 휴대폰 번호를 입력하세요."} -
-
- - setInputPhone(e.target.value)} - onKeyDown={(e) => {if (e.key === "Enter") handleClickSend()}} /> -
-
- ); -}; diff --git a/smartservice_frontend/src/lib/resetAccountPassword.ts b/smartservice_frontend/src/lib/resetAccountPassword.ts new file mode 100644 index 0000000..e032c70 --- /dev/null +++ b/smartservice_frontend/src/lib/resetAccountPassword.ts @@ -0,0 +1,28 @@ +import api from '@/lib/_AG'; + +/** + * Replaces an account's password with a random one and texts it to the given mobile number. + * Used by the account modify modals, with the mobile number typed in the modal. + */ +export const resetAccountPassword = (gid: string, phone: string) => { + if (!phone || phone.trim() == "") { + alert("휴대폰 번호를 입력하세요"); + return; + } + + if (!confirm("비밀번호를 초기화하고 " + phone + " 번호로 임시 비밀번호를 전송하시겠습니까?")) + return; + + api.post('/api/reset-account-password.do', { gid: gid, phone: phone }).then((resp) => { + console.log("reset-account-password", resp.data); + + if (resp.data.errCode == 0) + alert("임시 비밀번호 전송완료"); + else + alert("전송에 실패했습니다."); + }) + .catch((err) => { + console.error(err); + alert("전송에 실패했습니다."); + }); +};