1+ package com .ai .lawyer .global .initData ;
2+
3+ import com .ai .lawyer .domain .member .entity .Member ;
4+ import com .ai .lawyer .domain .member .repositories .MemberRepository ;
5+ import org .slf4j .Logger ;
6+ import org .slf4j .LoggerFactory ;
7+ import org .springframework .beans .factory .annotation .Value ;
8+ import org .springframework .boot .CommandLineRunner ;
9+ import org .springframework .boot .context .properties .ConfigurationProperties ;
10+ import org .springframework .security .crypto .password .PasswordEncoder ;
11+ import org .springframework .stereotype .Component ;
12+ import org .springframework .transaction .annotation .Transactional ;
13+
14+ import java .util .Optional ;
15+ import java .util .regex .Pattern ;
16+
17+ @ Component
18+ public class InitData implements CommandLineRunner {
19+ private static final Logger log = LoggerFactory .getLogger (InitData .class );
20+
21+ private final MemberRepository memberRepository ;
22+ private final PasswordEncoder passwordEncoder ;
23+
24+ // bcrypt 해시인지 판단하기 위한 간단 패턴
25+ private static final Pattern BCRYPT_PATTERN = Pattern .compile ("^\\ $2[aby]\\ $\\ d{2}\\ $.*" );
26+
27+ public InitData (MemberRepository memberRepository ,
28+ PasswordEncoder passwordEncoder ){
29+ this .memberRepository = memberRepository ;
30+ this .passwordEncoder = passwordEncoder ;
31+ }
32+
33+ @ Override
34+ @ Transactional
35+ public void run (String ... args ) throws Exception {
36+ //관리자 로그인 아이디
37+ String targetLoginId =
"[email protected] " ;
38+ log .info ("InitData: checking password encoding for [{}]" , targetLoginId );
39+
40+ Optional <Member > opt = memberRepository .findByLoginId (targetLoginId );
41+ if (opt .isEmpty ()) {
42+ log .info ("InitData: target account not found [{}]. 아무 작업도 수행하지 않습니다." , targetLoginId );
43+ return ;
44+ }
45+
46+ Member member = opt .get ();
47+ String stored = member .getPassword ();
48+
49+ if (isBcryptHash (stored )) {
50+ log .info ("InitData: {} 계정의 비밀번호는 이미 bcrypt 해시입니다. 변경 없음." , targetLoginId );
51+ return ;
52+ }
53+
54+ // 여기서 stored는 평문으로 추정됨 -> 절대 로그에 찍지 않음
55+ String encoded = passwordEncoder .encode (stored );
56+
57+ member .updatePassword (encoded );
58+ memberRepository .save (member );
59+
60+ log .info ("InitData: {} 계정의 비밀번호를 안전하게 암호화하여 저장했습니다." , targetLoginId );
61+ }
62+
63+ private boolean isBcryptHash (String s ) {
64+ return s != null && BCRYPT_PATTERN .matcher (s ).matches ();
65+ }
66+ }
0 commit comments