Skip to content

Commit 97f91ab

Browse files
authored
Merge pull request #311 from DevKor-github/codexd/korean-policy-pages
[codex] Add Korean policy pages
2 parents c02abf8 + ba1c5b7 commit 97f91ab

7 files changed

Lines changed: 887 additions & 397 deletions

File tree

ontime-back/src/main/java/devkor/ontime_back/config/SecurityConfig.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
7272
.headers(headers -> headers
7373
.frameOptions(frameOptions -> frameOptions.disable()))
7474
.authorizeHttpRequests(auth -> auth
75-
.requestMatchers("/", "/account-deletion", "/privacy-policy", "/css/**", "/images/**", "/js/**", "/favicon.ico", "/h2-console/**").permitAll()
75+
.requestMatchers("/", "/account-deletion", "/account-deletion/**", "/privacy-policy", "/privacy-policy/**", "/css/**", "/images/**", "/js/**", "/favicon.ico", "/h2-console/**").permitAll()
7676
.requestMatchers("/health", "/actuator/health/**", "/oauth2/sign-up", "oauth2/success", "login/success", "/oauth2/google/login", "/oauth2/kakao/login", "/oauth2/apple/login", "/sign-up", "/*/additional-info").permitAll()
7777
.requestMatchers("/v3/api-docs/**", "/swagger-ui/**", "/swagger-resources/**", "/webjars/**", "/swagger-ui.html").permitAll()
7878
.requestMatchers("/error").permitAll()

ontime-back/src/main/java/devkor/ontime_back/controller/AccountDeletionPageController.java

Lines changed: 278 additions & 127 deletions
Large diffs are not rendered by default.

ontime-back/src/main/java/devkor/ontime_back/controller/PrivacyPolicyController.java

Lines changed: 557 additions & 266 deletions
Large diffs are not rendered by default.

ontime-back/src/main/java/devkor/ontime_back/global/oauth/google/GoogleLoginService.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ private void logGoogleIdentityTokenClaims(String identityToken) {
192192
Long expirationTimeSeconds = payload.getExpirationTimeSeconds();
193193
long nowSeconds = System.currentTimeMillis() / 1000;
194194
log.info(
195-
"Google identity token claims aud={}, azp={}, iss={}, exp={}, now={}, secondsUntilExp={}, audienceAllowed={}",
195+
"Google identity credential claims aud={}, azp={}, iss={}, exp={}, now={}, secondsUntilExp={}, audienceAllowed={}",
196196
maskClientId(audience),
197197
payload.get("azp"),
198198
payload.getIssuer(),
@@ -202,7 +202,7 @@ private void logGoogleIdentityTokenClaims(String identityToken) {
202202
validClientIds.contains(audience)
203203
);
204204
} catch (Exception e) {
205-
log.info("Google identity token claim parsing failed: {}", e.getClass().getSimpleName());
205+
log.info("Google identity credential claim parsing failed: {}", e.getClass().getSimpleName());
206206
}
207207
}
208208

ontime-back/src/test/java/devkor/ontime_back/controller/AccountDeletionPageControllerTest.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,27 @@ void getAccountDeletionPage() throws Exception {
2222
.andExpect(status().isOk())
2323
.andExpect(header().string("Cache-Control", containsString("max-age=3600")))
2424
.andExpect(content().contentTypeCompatibleWith("text/html"))
25+
.andExpect(content().string(containsString("<html lang=\"ko\">")))
26+
.andExpect(content().string(containsString("OnTime 계정 삭제 요청")))
27+
.andExpect(content().string(containsString("앱 이름: OnTime")))
28+
.andExpect(content().string(containsString("개발자: ejun")))
29+
.andExpect(content().string(containsString("문의 이메일")))
30+
.andExpect(content().string(containsString("앱을 설치하거나 열지 않아도")))
31+
.andExpect(content().string(containsString("일정, 준비 데이터, 알림 일정")))
32+
.andExpect(content().string(containsString("최대 1년 동안 보관")))
33+
.andExpect(content().string(containsString("최대 90일 동안 보관")))
34+
.andExpect(content().string(containsString("30일을 초과하여 보관되지 않습니다")))
35+
.andExpect(content().string(containsString("https://ontime-back.duckdns.org/privacy-policy")));
36+
}
37+
38+
@DisplayName("영문 계정 삭제 요청 페이지를 로그인 없이 HTML로 조회한다.")
39+
@Test
40+
void getEnglishAccountDeletionPage() throws Exception {
41+
mockMvc.perform(get("/account-deletion/en"))
42+
.andExpect(status().isOk())
43+
.andExpect(header().string("Cache-Control", containsString("max-age=3600")))
44+
.andExpect(content().contentTypeCompatibleWith("text/html"))
45+
.andExpect(content().string(containsString("<html lang=\"en\">")))
2546
.andExpect(content().string(containsString("OnTime Account Deletion Request")))
2647
.andExpect(content().string(containsString("App name: OnTime")))
2748
.andExpect(content().string(containsString("Developer: ejun")))

ontime-back/src/test/java/devkor/ontime_back/controller/PrivacyPolicyControllerTest.java

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,33 @@ void getPrivacyPolicy() throws Exception {
2222
.andExpect(status().isOk())
2323
.andExpect(header().string("Cache-Control", containsString("max-age=3600")))
2424
.andExpect(content().contentTypeCompatibleWith("text/html"))
25+
.andExpect(content().string(containsString("<html lang=\"ko\">")))
26+
.andExpect(content().string(containsString("OnTime 개인정보 처리방침")))
27+
.andExpect(content().string(containsString("앱 이름: OnTime")))
28+
.andExpect(content().string(containsString("개발자/운영 주체: ejun")))
29+
.andExpect(content().string(containsString("문의 이메일")))
30+
.andExpect(content().string(containsString("시행일: 2026년 5월 10일")))
31+
.andExpect(content().string(containsString("https://ontime-back.duckdns.org/account-deletion")))
32+
.andExpect(content().string(containsString("계정 데이터")))
33+
.andExpect(content().string(containsString("일정/준비 데이터")))
34+
.andExpect(content().string(containsString("알람/알림 데이터")))
35+
.andExpect(content().string(containsString("피드백")))
36+
.andExpect(content().string(containsString("로컬 앱 데이터")))
37+
.andExpect(content().string(containsString("기술/진단 데이터")))
38+
.andExpect(content().string(containsString("계정 데이터와 사용자 소유 앱 데이터가 삭제됩니다")))
39+
.andExpect(content().string(containsString("최대 1년")))
40+
.andExpect(content().string(containsString("최대 90일")))
41+
.andExpect(content().string(containsString("30일을 초과하여")));
42+
}
43+
44+
@DisplayName("영문 개인정보 처리방침 페이지를 로그인 없이 HTML로 조회한다.")
45+
@Test
46+
void getEnglishPrivacyPolicy() throws Exception {
47+
mockMvc.perform(get("/privacy-policy/en"))
48+
.andExpect(status().isOk())
49+
.andExpect(header().string("Cache-Control", containsString("max-age=3600")))
50+
.andExpect(content().contentTypeCompatibleWith("text/html"))
51+
.andExpect(content().string(containsString("<html lang=\"en\">")))
2552
.andExpect(content().string(containsString("OnTime Privacy Policy")))
2653
.andExpect(content().string(containsString("App name: OnTime")))
2754
.andExpect(content().string(containsString("Developer/entity: ejun")))

ontime-back/src/test/java/devkor/ontime_back/global/jwt/JwtAuthenticationFilterTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ class JwtAuthenticationFilterTest {
1616

1717
@DisplayName("공개 HTML 페이지는 액세스 토큰 없이 JWT 필터를 통과한다.")
1818
@ParameterizedTest
19-
@ValueSource(strings = {"/account-deletion", "/privacy-policy"})
19+
@ValueSource(strings = {"/account-deletion", "/account-deletion/en", "/privacy-policy", "/privacy-policy/en"})
2020
void skipsPublicHtmlPages(String path) throws Exception {
2121
JwtTokenProvider jwtTokenProvider = mock(JwtTokenProvider.class);
2222
UserRepository userRepository = mock(UserRepository.class);

0 commit comments

Comments
 (0)