create-entity-server 0.0.31 → 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/package.json +1 -1
  2. package/template/configs/database.json +18 -7
  3. package/template/entities/README.md +3 -3
  4. package/template/entities/System/Address/addr_dong.json +10115 -0
  5. package/template/entities/System/Address/addr_sido.json +39 -0
  6. package/template/entities/System/Address/addr_sigungu.json +1398 -0
  7. package/template/entities/System/Auth/account.json +0 -64
  8. package/template/entities/System/Auth/account_device.json +7 -22
  9. package/template/entities/System/Auth/account_login_log.json +3 -8
  10. package/template/entities/System/Auth/anon_device.json +56 -0
  11. package/template/scripts/reset-all.sh +78 -5
  12. package/template/scripts/run.sh +73 -27
  13. package/template/configs/auth/oauth.json +0 -40
  14. package/template/configs/auth/password.json +0 -45
  15. package/template/configs/keys/apns.p8.example +0 -7
  16. package/template/configs/keys/firebase.pem.example +0 -7
  17. package/template/configs/notification/push.json +0 -25
  18. package/template/entities/System/Auth/account_oauth.json +0 -74
  19. package/template/entities/System/Auth/identity_verification.json +0 -106
  20. package/template/entities/System/Auth/password_history.json +0 -19
  21. package/template/entities/System/Notification/alimtalk_log.json +0 -65
  22. package/template/entities/System/Notification/alimtalk_msg.json +0 -53
  23. package/template/entities/System/Notification/friendtalk_log.json +0 -89
  24. package/template/entities/System/Notification/friendtalk_msg.json +0 -91
  25. package/template/entities/System/Notification/sms_log.json +0 -65
  26. package/template/entities/System/Notification/sms_msg.json +0 -82
  27. package/template/entities/System/Notification/sms_verification.json +0 -50
  28. package/template/entities/System/Payment/pg_cancel.json +0 -60
  29. package/template/entities/System/Payment/pg_order.json +0 -115
  30. package/template/entities/System/Payment/pg_webhook_log.json +0 -52
  31. package/template/entities/System/Push/push_log.json +0 -86
  32. package/template/entities/System/Push/push_msg.json +0 -56
  33. package/template/templates/email/auth/2fa_disabled.html +0 -23
  34. package/template/templates/email/auth/2fa_recovery_regenerated.html +0 -31
  35. package/template/templates/email/auth/2fa_setup_complete.html +0 -43
  36. package/template/templates/email/auth/welcome.html +0 -18
  37. package/template/templates/email/order/order_confirmation.html +0 -30
  38. /package/template/configs/{notification/smtp.json → smtp.json} +0 -0
@@ -22,10 +22,6 @@
22
22
  "type": ["active", "inactive", "blocked", "dormant"],
23
23
  "default": "active"
24
24
  },
25
- "user_seq": {
26
- "index": true,
27
- "comment": "사용자번호"
28
- },
29
25
  "max_session_cnt": {
30
26
  "type": "uint"
31
27
  },
@@ -50,26 +46,6 @@
50
46
  "type": "bool",
51
47
  "default": false,
52
48
  "comment": "다음 로그인 시 비밀번호 변경 강제"
53
- },
54
- "name": {
55
- "no_store": true,
56
- "comment": "가입 요청 시 전달되는 이름. account에는 저장되지 않고 after_insert 훅(user 엔티티 생성 등)에서만 사용됩니다."
57
- },
58
- "phone": {
59
- "no_store": true,
60
- "comment": "가입 요청 시 전달되는 전화번호. no_store."
61
- },
62
- "birth_date": {
63
- "no_store": true,
64
- "comment": "가입 요청 시 전달되는 생년월일. no_store."
65
- },
66
- "gender": {
67
- "no_store": true,
68
- "comment": "가입 요청 시 전달되는 성별. no_store."
69
- },
70
- "profile_image": {
71
- "no_store": true,
72
- "comment": "가입 요청 시 전달되는 프로필 이미지. no_store."
73
49
  }
74
50
  },
75
51
  "reset_defaults": [
@@ -129,21 +105,6 @@
129
105
  "query": "INSERT INTO account_audit (account_seq, action, email, created_time) VALUES (?, ?, ?, NOW())",
130
106
  "params": ["${new.seq}", "INSERT", "${new.email}"],
131
107
  "required": true
132
- },
133
- {
134
- "_comment": "가입 시 user 엔티티 자동 생성. enabled: true로 바꾸면 활성화됩니다. assign_seq_to로 account.user_seq에 자동 반영됩니다.",
135
- "type": "submit",
136
- "enabled": false,
137
- "entity": "user",
138
- "data": {
139
- "account_seq": "${new.seq}",
140
- "name": "${new.name}",
141
- "phone": "${new.phone}",
142
- "birth_date": "${new.birth_date}",
143
- "gender": "${new.gender}",
144
- "profile_image": "${new.profile_image}"
145
- },
146
- "assign_seq_to": "user_seq"
147
108
  }
148
109
  ],
149
110
  "after_update": [
@@ -152,22 +113,6 @@
152
113
  "query": "INSERT INTO account_audit (account_seq, action, email, created_time) VALUES (?, ?, ?, NOW())",
153
114
  "params": ["${new.seq}", "UPDATE", "${new.email}"],
154
115
  "required": true
155
- },
156
- {
157
- "_comment": "계정 업데이트 시 user 프로필 동기화. enabled: true로 바꾸면 활성화됩니다.",
158
- "type": "submit",
159
- "enabled": false,
160
- "entity": "user",
161
- "match": {
162
- "account_seq": "${new.seq}"
163
- },
164
- "data": {
165
- "name": "${new.name}",
166
- "phone": "${new.phone}",
167
- "birth_date": "${new.birth_date}",
168
- "gender": "${new.gender}",
169
- "profile_image": "${new.profile_image}"
170
- }
171
116
  }
172
117
  ],
173
118
  "after_delete": [
@@ -179,15 +124,6 @@
179
124
  }
180
125
  ],
181
126
  "after_get": [
182
- {
183
- "type": "entity",
184
- "entity": "user",
185
- "action": "find",
186
- "conditions": {
187
- "seq": "${new.user_seq}"
188
- },
189
- "assign_to": "user_profile"
190
- },
191
127
  {
192
128
  "type": "entity",
193
129
  "entity": "account_device",
@@ -1,11 +1,12 @@
1
1
  {
2
2
  "name": "account_device",
3
- "description": "계정 기기 정보 및 푸시 토큰 관리. JWT 인증 시 account_seq로 계정과 연결. 사용자 환경에 맞게 fields를 자유롭게 확장할 수 있습니다.",
3
+ "description": "회원 계정 기기 정보 및 푸시 토큰 관리. account_seq로 계정과 연결되며 회원 전용으로 사용합니다. 사용자 환경에 맞게 fields를 자유롭게 확장할 수 있습니다.",
4
4
  "license_scope": false,
5
5
  "fields": {
6
6
  "account_seq": {
7
7
  "index": true,
8
- "comment": "계정seq (JWT 인증 시 필수. HMAC 인증은 nullable)"
8
+ "required": true,
9
+ "comment": "계정seq (회원 계정 필수)"
9
10
  },
10
11
  "id": {
11
12
  "index": true,
@@ -19,24 +20,12 @@
19
20
  },
20
21
  "device_type": {
21
22
  "comment": "기기유형",
22
- "type": [
23
- "mobile",
24
- "tablet",
25
- "desktop",
26
- "watch"
27
- ],
23
+ "type": ["mobile", "tablet", "desktop", "watch"],
28
24
  "default": "mobile"
29
25
  },
30
26
  "platform": {
31
27
  "comment": "플랫폼",
32
- "type": [
33
- "android",
34
- "ios",
35
- "web",
36
- "windows",
37
- "macos",
38
- "linux"
39
- ]
28
+ "type": ["android", "ios", "web", "windows", "macos", "linux"]
40
29
  },
41
30
  "browser": {
42
31
  "comment": "브라우저"
@@ -55,10 +44,6 @@
55
44
  "comment": "마지막IP주소"
56
45
  }
57
46
  },
58
- "unique": [
59
- [
60
- "id",
61
- "account_seq"
62
- ]
63
- ]
47
+ "unique": [["id", "account_seq"]],
48
+ "history": false
64
49
  }
@@ -41,19 +41,14 @@
41
41
  "language": {
42
42
  "comment": "언어"
43
43
  },
44
- "user_seq": {
44
+ "account_seq": {
45
45
  "index": true,
46
- "comment": "사용자번호"
46
+ "comment": "계정번호"
47
47
  },
48
48
  "auth_method": {
49
49
  "index": true,
50
50
  "comment": "인증 방식",
51
- "type": [
52
- "password",
53
- "oauth",
54
- "2fa_totp",
55
- "2fa_recovery"
56
- ],
51
+ "type": ["password", "oauth", "2fa_totp", "2fa_recovery"],
57
52
  "default": "password"
58
53
  },
59
54
  "location_info": {
@@ -0,0 +1,56 @@
1
+ {
2
+ "name": "anon_device",
3
+ "description": "비회원 디바이스 식별 및 사용 제한 집계. device_id 쿠키 값 기반으로 추적하며 익명 사용자 전용으로 사용합니다. 사용자 환경에 맞게 fields를 자유롭게 확장할 수 있습니다.",
4
+ "license_scope": false,
5
+ "fields": {
6
+ "id": {
7
+ "index": true,
8
+ "required": true,
9
+ "unique": true,
10
+ "comment": "익명 디바이스 ID (cookie/device_id)"
11
+ },
12
+ "calc_count": {
13
+ "index": true,
14
+ "type": "uint",
15
+ "default": 0,
16
+ "comment": "거리 계산 사용 횟수"
17
+ },
18
+ "first_seen_time": {
19
+ "comment": "최초 식별 시각"
20
+ },
21
+ "last_seen_time": {
22
+ "index": true,
23
+ "comment": "마지막 식별 시각"
24
+ },
25
+ "last_calc_time": {
26
+ "index": true,
27
+ "comment": "마지막 거리 계산 시각"
28
+ },
29
+ "blocked_until_time": {
30
+ "index": true,
31
+ "comment": "차단 해제 시각"
32
+ },
33
+ "last_ip_addr": {
34
+ "comment": "마지막 IP주소"
35
+ },
36
+ "device_type": {
37
+ "comment": "기기유형",
38
+ "type": ["mobile", "tablet", "desktop", "watch"],
39
+ "default": "mobile"
40
+ },
41
+ "platform": {
42
+ "comment": "플랫폼",
43
+ "type": ["android", "ios", "web", "windows", "macos", "linux"]
44
+ },
45
+ "browser": {
46
+ "comment": "브라우저"
47
+ },
48
+ "browser_version": {
49
+ "comment": "브라우저버전"
50
+ },
51
+ "user_agent": {
52
+ "comment": "User Agent"
53
+ }
54
+ },
55
+ "history": false
56
+ }
@@ -25,6 +25,75 @@ if [ -f .env ]; then
25
25
  fi
26
26
  LANGUAGE=${LANGUAGE:-ko}
27
27
 
28
+ get_env_value() {
29
+ local key="$1"
30
+ local value="${!key}"
31
+
32
+ if [ -n "$value" ]; then
33
+ echo "$value"
34
+ return
35
+ fi
36
+
37
+ if [ -f .env ]; then
38
+ value=$(grep -E "^${key}=" .env | tail -n 1 | cut -d '=' -f2-)
39
+ echo "$value"
40
+ fi
41
+ }
42
+
43
+ get_database_default_group() {
44
+ grep -E '"default"[[:space:]]*:' "$PROJECT_ROOT/configs/database.json" \
45
+ | head -n 1 \
46
+ | sed -E 's/.*:[[:space:]]*"([^"]+)".*/\1/'
47
+ }
48
+
49
+ get_database_group_field() {
50
+ local group="$1"
51
+ local field="$2"
52
+
53
+ awk -v group="$group" -v field="$field" '
54
+ $0 ~ "^[[:space:]]*\"" group "\"[[:space:]]*:[[:space:]]*\\{" { in_group=1; next }
55
+ in_group && $0 ~ "^[[:space:]]*}" { exit }
56
+ in_group && $0 ~ "^[[:space:]]*\"" field "\"[[:space:]]*:" {
57
+ match($0, /"[^"]+"[[:space:]]*:[[:space:]]*"([^"]+)"/, arr)
58
+ if (arr[1] != "") {
59
+ print arr[1]
60
+ }
61
+ exit
62
+ }
63
+ ' "$PROJECT_ROOT/configs/database.json"
64
+ }
65
+
66
+ resolve_database_name() {
67
+ local group="$1"
68
+ local raw_value
69
+ raw_value=$(get_database_group_field "$group" "database")
70
+
71
+ if [[ "$raw_value" =~ ^\$\{([A-Z0-9_]+)\}$ ]]; then
72
+ get_env_value "${BASH_REMATCH[1]}"
73
+ return
74
+ fi
75
+
76
+ echo "$raw_value"
77
+ }
78
+
79
+ print_target_database() {
80
+ local group
81
+ local database_name
82
+
83
+ group=$(get_database_default_group)
84
+ database_name=$(resolve_database_name "$group")
85
+
86
+ echo ""
87
+ if [ "$LANGUAGE" = "en" ]; then
88
+ echo "Target database group: ${group:-<unknown>}"
89
+ echo "Target database name : ${database_name:-<unknown>}"
90
+ else
91
+ echo "대상 DB 그룹 : ${group:-<unknown>}"
92
+ echo "대상 DB 이름 : ${database_name:-<unknown>}"
93
+ fi
94
+ echo ""
95
+ }
96
+
28
97
  # Show usage if no arguments
29
98
  if [ $# -eq 0 ]; then
30
99
  if [ "$LANGUAGE" = "en" ]; then
@@ -78,9 +147,11 @@ fi
78
147
  # Execute based on flag
79
148
  case "$1" in
80
149
  --dry-run)
150
+ print_target_database
81
151
  "$PROJECT_ROOT/bin/entity-cli" reset-all
82
152
  ;;
83
153
  --force|--apply)
154
+ print_target_database
84
155
  # 필수 엔티티 없으면 자동 생성 (api_keys, rbac_roles, account, user)
85
156
  if [ "$LANGUAGE" = "en" ]; then
86
157
  echo "⚙️ Checking required entities..."
@@ -88,6 +159,7 @@ case "$1" in
88
159
  echo "⚙️ 필수 엔티티 확인 중..."
89
160
  fi
90
161
  LANGUAGE="$LANGUAGE" "$SCRIPT_DIR/normalize-entities.sh" --apply
162
+
91
163
  RESET_LOG=$(mktemp)
92
164
  if [ "$1" = "--force" ]; then
93
165
  set +e
@@ -123,15 +195,16 @@ case "$1" in
123
195
  echo " ENTITY_API_KEY = $NEW_API_KEY"
124
196
  echo " ENTITY_HMAC_SECRET = $NEW_HMAC"
125
197
 
126
- # 게이트웨이 .env 자동 업데이트 (같은 저장소 내에 있는 경우)
127
- GW_ENV="$PROJECT_ROOT/packages/entity-app-server/.env"
128
- if [ -f "$GW_ENV" ]; then
198
+ # 게이트웨이 .env 자동 업데이트 (개발 환경: entity-app-server/ 폴더가 같은 레벨에 있을 때만)
199
+ GW_DIR="$(dirname "$PROJECT_ROOT")/entity-app-server"
200
+ GW_ENV="$GW_DIR/.env"
201
+ if [ -d "$GW_DIR" ] && [ -f "$GW_ENV" ]; then
129
202
  sed -i "s|^ENTITY_API_KEY=.*|ENTITY_API_KEY=$NEW_API_KEY|" "$GW_ENV"
130
203
  sed -i "s|^ENTITY_HMAC_SECRET=.*|ENTITY_HMAC_SECRET=$NEW_HMAC|" "$GW_ENV"
131
204
  if [ "$LANGUAGE" = "en" ]; then
132
- echo " ✓ Updated: packages/entity-app-server/.env"
205
+ echo " ✓ Updated: entity-app-server/.env"
133
206
  else
134
- echo " ✓ 업데이트 완료: packages/entity-app-server/.env"
207
+ echo " ✓ 업데이트 완료: entity-app-server/.env"
135
208
  fi
136
209
  fi
137
210
  fi
@@ -54,6 +54,70 @@ get_server_value() {
54
54
  fi
55
55
  }
56
56
 
57
+ get_database_default_group() {
58
+ local value
59
+ value=$(grep -E '"default"[[:space:]]*:' "$DATABASE_CONFIG" | head -n 1 | sed -E 's/.*:[[:space:]]*"([^"]+)".*/\1/')
60
+ echo "$value"
61
+ }
62
+
63
+ list_database_groups() {
64
+ grep -E '^[[:space:]]*"[^"]+"[[:space:]]*:[[:space:]]*\{' "$DATABASE_CONFIG" \
65
+ | sed -E 's/^[[:space:]]*"([^"]+)"[[:space:]]*:[[:space:]]*\{.*/\1/' \
66
+ | grep -v '^groups$' \
67
+ | awk 'BEGIN { first = 1 } { if (!first) printf ", "; printf "%s", $0; first = 0 } END { printf "\n" }'
68
+ }
69
+
70
+ print_missing_database_group_error() {
71
+ local expected_group="$1"
72
+ local line_no="$2"
73
+ local current_default
74
+ local available_groups
75
+
76
+ current_default=$(get_database_default_group)
77
+ available_groups=$(list_database_groups)
78
+
79
+ if [ "$LANGUAGE" = "en" ]; then
80
+ echo "❌ database group '$expected_group' not found"
81
+ echo " at: scripts/run.sh:$line_no"
82
+ echo " config: $DATABASE_CONFIG"
83
+ echo " current default: ${current_default:-<empty>}"
84
+ echo " available groups: ${available_groups:-<none>}"
85
+ echo " cause: run.sh $MODE hardcodes '$expected_group' as the target default group."
86
+ else
87
+ echo "❌ configs/database.json에 '$expected_group' 그룹이 없습니다"
88
+ echo " 위치: scripts/run.sh:$line_no"
89
+ echo " 설정파일: $DATABASE_CONFIG"
90
+ echo " 현재 default: ${current_default:-<empty>}"
91
+ echo " 사용 가능한 groups: ${available_groups:-<none>}"
92
+ echo " 원인: run.sh $MODE 모드는 '$expected_group' 그룹을 기본 DB 그룹으로 강제하도록 작성되어 있습니다."
93
+ fi
94
+ }
95
+
96
+ sync_database_default_for_environment() {
97
+ local environment_value
98
+ environment_value=$(get_server_value "environment" "development")
99
+
100
+ if [ "$environment_value" != "production" ]; then
101
+ return 0
102
+ fi
103
+
104
+ # 현재 default 그룹이 database.json 안에 존재하면 그대로 유지
105
+ local current_default
106
+ current_default=$(get_database_default_group)
107
+ if [ -n "$current_default" ] && grep -Eq "\"${current_default}\"[[:space:]]*:" "$DATABASE_CONFIG"; then
108
+ return 0
109
+ fi
110
+
111
+ # 현재 default 그룹이 없을 때만 production으로 fallback
112
+ if ! grep -Eq '"production"[[:space:]]*:' "$DATABASE_CONFIG"; then
113
+ print_missing_database_group_error "production" "$1"
114
+ return 1
115
+ fi
116
+
117
+ sed -E -i 's/("default"[[:space:]]*:[[:space:]]*")[^"]+(")/\1production\2/' "$DATABASE_CONFIG"
118
+ return 0
119
+ }
120
+
57
121
  is_running() {
58
122
  local port_pid
59
123
  port_pid=$(find_pid_by_port)
@@ -146,7 +210,7 @@ stop_pid_with_confirm() {
146
210
  read -r -p "이 프로세스를 중지할까요? [y/N]: " input
147
211
  fi
148
212
  input=$(echo "$input" | tr '[:upper:]' '[:lower:]')
149
- if [ "$input" != "y" ] && [ "$input" != "yes" ]; then
213
+ if [ "$input" != "y" ] && [ "$input" != "yes" ] && [ "$input" != "ㅛ" ]; then
150
214
  if [ "$LANGUAGE" = "en" ]; then
151
215
  echo "Canceled."
152
216
  else
@@ -273,13 +337,13 @@ if [ $# -eq 0 ]; then
273
337
  echo "Entity Server - Run Script"
274
338
  echo "=========================="
275
339
  echo ""
276
- echo "Force configs/server.json environment and configs/database.json default group, then start compiled server binary."
340
+ echo "Adjust configs/server.json environment as needed, then start the compiled server binary."
277
341
  echo ""
278
342
  echo "Usage: $0 <mode>"
279
343
  echo ""
280
344
  echo "Modes:"
281
- echo " dev environment=development, database.default=development, then run binary"
282
- echo " start environment=production, database.default=production, then run in background"
345
+ echo " dev environment=development, keep database.default, then run binary"
346
+ echo " start environment=production, use database.default=production only in production, then run in background"
283
347
  echo " stop stop background server started by this script"
284
348
  echo " status show server status"
285
349
  echo ""
@@ -292,13 +356,13 @@ if [ $# -eq 0 ]; then
292
356
  echo "Entity Server - 실행 스크립트"
293
357
  echo "==========================="
294
358
  echo ""
295
- echo "configs/server.json의 environment configs/database.json의 default를 강제 설정하고 바이너리를 실행합니다."
359
+ echo "configs/server.json의 environment 기준으로 필요한 경우에만 database.default를 조정한 바이너리를 실행합니다."
296
360
  echo ""
297
361
  echo "사용법: $0 <모드>"
298
362
  echo ""
299
363
  echo "모드:"
300
- echo " dev environment=development, database.default=development 강제 바이너리 실행"
301
- echo " start environment=production, database.default=production 강제 백그라운드 실행"
364
+ echo " dev environment=development 설정하고 database.default 유지한 바이너리 실행"
365
+ echo " start environment=production으로 설정하고 production일 때만 database.default=production으로 맞춘 백그라운드 실행"
302
366
  echo " stop run.sh로 백그라운드 실행한 서버 중지"
303
367
  echo " status 서버 상태 조회"
304
368
  echo ""
@@ -357,17 +421,8 @@ case "$MODE" in
357
421
  exit 1
358
422
  fi
359
423
 
360
- if ! grep -Eq '"development"[[:space:]]*:' "$DATABASE_CONFIG"; then
361
- if [ "$LANGUAGE" = "en" ]; then
362
- echo "❌ database group 'development' not found in configs/database.json"
363
- else
364
- echo "❌ configs/database.json에 'development' 그룹이 없습니다"
365
- fi
366
- exit 1
367
- fi
368
-
369
424
  sed -E -i 's/("environment"[[:space:]]*:[[:space:]]*")[^"]+(")/\1development\2/' "$SERVER_CONFIG"
370
- sed -E -i 's/("default"[[:space:]]*:[[:space:]]*")[^"]+(")/\1development\2/' "$DATABASE_CONFIG"
425
+ sync_database_default_for_environment "$LINENO" || exit 1
371
426
  "$SERVER_BIN"
372
427
  ;;
373
428
 
@@ -387,17 +442,8 @@ case "$MODE" in
387
442
  exit 1
388
443
  fi
389
444
 
390
- if ! grep -Eq '"production"[[:space:]]*:' "$DATABASE_CONFIG"; then
391
- if [ "$LANGUAGE" = "en" ]; then
392
- echo "❌ database group 'production' not found in configs/database.json"
393
- else
394
- echo "❌ configs/database.json에 'production' 그룹이 없습니다"
395
- fi
396
- exit 1
397
- fi
398
-
399
445
  sed -E -i 's/("environment"[[:space:]]*:[[:space:]]*")[^"]+(")/\1production\2/' "$SERVER_CONFIG"
400
- sed -E -i 's/("default"[[:space:]]*:[[:space:]]*")[^"]+(")/\1production\2/' "$DATABASE_CONFIG"
446
+ sync_database_default_for_environment "$LINENO" || exit 1
401
447
 
402
448
  "$SERVER_BIN" banner
403
449
  nohup "$SERVER_BIN" >> "$STDOUT_LOG" 2>&1 &
@@ -1,40 +0,0 @@
1
- {
2
- "_comment": "OAuth 2.0 설정 예시. 사용할 프로바이더만 남기고 실제 값으로 교체하세요.",
3
- "enabled": false,
4
-
5
- "state_secret": "${OAUTH_STATE_SECRET}",
6
- "state_ttl_sec": 600,
7
- "success_redirect_url": "/auth/callback",
8
- "failure_redirect_url": "/auth/error",
9
-
10
- "providers": {
11
- "google": {
12
- "client_id": "${GOOGLE_CLIENT_ID}",
13
- "client_secret": "${GOOGLE_CLIENT_SECRET}",
14
- "redirect_url": "/v1/oauth/google/callback",
15
- "scopes": ["openid", "email", "profile"]
16
- },
17
- "github": {
18
- "client_id": "${GITHUB_CLIENT_ID}",
19
- "client_secret": "${GITHUB_CLIENT_SECRET}",
20
- "redirect_url": "/v1/oauth/github/callback"
21
- },
22
- "naver": {
23
- "client_id": "${NAVER_CLIENT_ID}",
24
- "client_secret": "${NAVER_CLIENT_SECRET}",
25
- "redirect_url": "/v1/oauth/naver/callback"
26
- },
27
- "kakao": {
28
- "_comment": "Kakao — 커스텀 엔드포인트 예시",
29
- "client_id": "${KAKAO_CLIENT_ID}",
30
- "client_secret": "${KAKAO_CLIENT_SECRET}",
31
- "redirect_url": "/v1/oauth/kakao/callback",
32
- "auth_url": "https://kauth.kakao.com/oauth/authorize",
33
- "token_url": "https://kauth.kakao.com/oauth/token",
34
- "user_info_url": "https://kapi.kakao.com/v2/user/me",
35
- "scopes": ["profile_nickname", "account_email"],
36
- "email_field": "kakao_account.email",
37
- "name_field": "properties.nickname"
38
- }
39
- }
40
- }
@@ -1,45 +0,0 @@
1
- {
2
- "password_policy": {
3
- "min_length": 8,
4
- "max_length": 128,
5
- "require_mixed_case": false,
6
- "require_number": false,
7
- "require_special": false,
8
- "history_count": 5,
9
- "forbidden_patterns": {
10
- "sequential_digits": true,
11
- "repeated_chars": true,
12
- "keyboard_patterns": false,
13
- "sequential_length": 4
14
- },
15
- "pii_check": {
16
- "enabled": false,
17
- "entity": "user",
18
- "fields": ["phone", "birthday"]
19
- }
20
- },
21
- "admin_force_reset": {
22
- "temp_password_length": 12,
23
- "require_change": true,
24
- "notify_email": true
25
- },
26
- "password_reset": {
27
- "enabled": true,
28
- "temp_password_ttl_sec": 300,
29
- "temp_password_length": 12,
30
- "rate_limit": {
31
- "per_email_per_hour": 5,
32
- "per_ip_per_minute": 10
33
- }
34
- },
35
- "email_verification": {
36
- "enabled": true,
37
- "required": false,
38
- "code_length": 6,
39
- "code_ttl_sec": 300,
40
- "max_attempts": 5,
41
- "rate_limit": {
42
- "per_email_per_hour": 5
43
- }
44
- }
45
- }
@@ -1,7 +0,0 @@
1
- -----BEGIN PRIVATE KEY-----
2
- (샘플) Apple Developer Console → Certificates, Identifiers & Profiles
3
- → Keys → "+" 버튼으로 APNs 키 생성 후 다운로드한 .p8 파일 내용을 여기에 붙여넣으세요.
4
-
5
- 실제 키는 아래와 같은 형식입니다:
6
- MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg...
7
- -----END PRIVATE KEY-----
@@ -1,7 +0,0 @@
1
- -----BEGIN PRIVATE KEY-----
2
- (샘플) Firebase Console → 프로젝트 설정 → 서비스 계정 → 새 비공개 키 생성
3
- 으로 다운로드한 JSON 파일의 private_key 값을 여기에 붙여넣으세요.
4
-
5
- 실제 키는 아래와 같은 형식입니다:
6
- MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC...
7
- -----END PRIVATE KEY-----
@@ -1,25 +0,0 @@
1
- {
2
- "workers": 2,
3
- "queue_size": 500,
4
- "fcm": {
5
- "enabled": false,
6
- "type": "service_account",
7
- "project_id": "your-firebase-project-id",
8
- "private_key_id": "abc123def456...",
9
- "private_key_file": "./configs/keys/firebase.pem",
10
- "client_email": "firebase-adminsdk-xxxxx@your-firebase-project-id.iam.gserviceaccount.com",
11
- "client_id": "123456789012345678901",
12
- "auth_uri": "https://accounts.google.com/o/oauth2/auth",
13
- "token_uri": "https://oauth2.googleapis.com/token",
14
- "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
15
- "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/firebase-adminsdk-xxxxx%40your-firebase-project-id.iam.gserviceaccount.com"
16
- },
17
- "apns": {
18
- "enabled": false,
19
- "key_file": "./configs/keys/apns.p8",
20
- "key_id": "ABCDE12345",
21
- "team_id": "FGHIJ67890",
22
- "bundle_id": "com.example.myapp",
23
- "production": false
24
- }
25
- }