Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
96 commits
Select commit Hold shift + click to select a range
852d39e
[BUILD] docker-compose에 redis추가
May 26, 2025
7d9a812
[CI]GitHub Actions 워크플로 추가 및 자동 배포 테스트1
May 27, 2025
1cded10
[CI] GitHub Actions 워크플로 추가 및 자동 배포 테스트1
May 27, 2025
390ae99
Merge branch 'develop' of https://github.com/suyoungSwim/spring-vote-…
May 27, 2025
4c832de
[CI] GitHub Actions 워크플로 추가 ë° 수ì  ™ 배포 테스트트2
May 27, 2025
8b1ccaa
[CI] GitHub Actionapi 수정í• 후 CI CD Test3
May 27, 2025
090a278
[CI] GitHub Actionapi 수정í ›„ CI CD Test4
May 27, 2025
d957136
[CHORE] SecurityConfig에서 cors 허용
May 27, 2025
f73777e
Merge pull request #24 from suyoungSwim/chore/#23-cors
WithFortuna May 28, 2025
c63e932
[FEAT] 공통 응답 전송 기능 구현
WithFortuna Jun 7, 2025
c9321e8
[REFACTOR] 기존 ErrorCode를 더 범용적인 ServiceCode로 변경
WithFortuna Jun 7, 2025
3794e4a
[FEAT] 투표 생성 시각 추가
WithFortuna Jun 7, 2025
81f09c6
[REFACTOR] 헬스체크 경로 변경
WithFortuna Jun 7, 2025
b976d27
[FEAT] username, email 중복 확인 기능
WithFortuna Jun 7, 2025
90185ae
[FEAT] 테스트 클래스에 환경변수 적용 테스팅
WithFortuna Jun 7, 2025
41655a4
[REFACTOR] DTO 하위 패키지 추가
WithFortuna Jun 7, 2025
716fffd
[FEAT] 테스트 클래스에 환경변수 적용 테스팅
WithFortuna Jun 7, 2025
ef82c92
[FEAT] ElectionController 구현
WithFortuna Jun 7, 2025
7f17190
[FEAT] 투표하기 엔드포인트 구현
WithFortuna Jun 7, 2025
37f234e
[FEAT] 인증 요구 여부와는 무관하게 JwtAuthorizationFilter 통과
WithFortuna Jun 7, 2025
60530c2
[STYLE] 주석 추가
WithFortuna Jun 7, 2025
99ff18f
Merge branch 'develop' into feature/#26-common-response
WithFortuna Jun 7, 2025
cfee180
[FEAT] CorsConfig 클래스 설정
WithFortuna Jun 7, 2025
8822bc0
[FEAT] 투표 여부 및 정보 API
WithFortuna Jun 7, 2025
2904035
[STYLE] 불필요 import 제거
WithFortuna Jun 7, 2025
7157a3a
Merge pull request #27 from suyoungSwim/feature/#26-common-response
WithFortuna Jun 8, 2025
be2e23e
Merge branch 'develop' into feature/#29-vote-api
WithFortuna Jun 8, 2025
c63e750
Merge pull request #30 from suyoungSwim/feature/#29-vote-api
WithFortuna Jun 8, 2025
1be8929
[FEAT] 토큰 재발급 엔드포인트 구현
WithFortuna Jun 14, 2025
db753f4
Revert "[FEAT] 토큰 재발급 엔드포인트 구현"
WithFortuna Jun 14, 2025
35081b2
Revert "Revert "[FEAT] 토큰 재발급 엔드포인트 구현""
WithFortuna Jun 14, 2025
bd0d1ed
Merge pull request #35 from suyoungSwim/feature/34-reissue-token
WithFortuna Jun 14, 2025
89f1cab
[CHORE] swagger-ui 적용
WithFortuna Jun 14, 2025
5733257
Merge pull request #37 from suyoungSwim/feature/34-reissue-token
WithFortuna Jun 14, 2025
221a642
[FIX] SecurityConfig 인증 불필요 경로 수정
WithFortuna Jun 14, 2025
a354210
Merge pull request #39 from suyoungSwim/fix/#38-authentciated-path
WithFortuna Jun 14, 2025
8ffdb0b
[FEAT] 선거, 회원 모두 삭제 기능
WithFortuna Jun 15, 2025
d6f0437
[FEAT] URI 인증/인가
WithFortuna Jun 15, 2025
449c466
Merge pull request #40 from suyoungSwim/feature/#38-uri-authentication
WithFortuna Jun 15, 2025
1b44f7d
[FEAT] 테스트용 헬스체크2
WithFortuna Jun 15, 2025
b06d2f3
[FEAT] 테스트용 헬스체크2
WithFortuna Jun 15, 2025
b8db9b0
Merge pull request #41 from suyoungSwim/feature/#38-uri-authentication
WithFortuna Jun 15, 2025
e513d95
[FEAT] SwaggerConfig 추가
WithFortuna Jun 15, 2025
788dcca
Merge pull request #43 from suyoungSwim/feature/#38-uri-authentication
WithFortuna Jun 15, 2025
59cf3ab
[FEAT] Swagger 인증기능 추가
WithFortuna Jun 15, 2025
f837b25
[FEAT] Swagger 엔드포인트 추가
WithFortuna Jun 15, 2025
f727e66
[FIX] 로그아웃 필터 반영
WithFortuna Jun 15, 2025
9c84ea2
Merge pull request #46 from suyoungSwim/feature/#44-swagger-login
WithFortuna Jun 16, 2025
05ac63f
[FEAT] GlobalExceptionHandler 스웨거 제외
WithFortuna Jun 20, 2025
b82c683
[FEAT] 쿠키 옵션 변경
WithFortuna Jun 20, 2025
a891586
Merge pull request #48 from suyoungSwim/feature/#47-cookie
WithFortuna Jun 20, 2025
3c73a21
[FEAT] CORS 허용할 오리진 변경
WithFortuna Jun 20, 2025
cd1fbc6
Merge pull request #49 from suyoungSwim/feature/#47-cookie
WithFortuna Jun 20, 2025
c144877
[FEAT] Update CorsConfig.java
WithFortuna Jun 20, 2025
537d10f
[FIX] Update CorsConfig.java
WithFortuna Jun 20, 2025
6afd918
[STYLE] RefreshToken 처리 로그
WithFortuna Jun 20, 2025
2f9f0ab
[REFACTOR] Update SecurityConfig.java
WithFortuna Jun 20, 2025
2ebde8c
[REFACTOR] Update SecurityConfig.java
WithFortuna Jun 20, 2025
ef58bdb
[FIX] test FE 주소 수정
WithFortuna Jun 20, 2025
5c70a64
[STYLE] Cookie 주석
WithFortuna Jun 20, 2025
239f38e
[REFACTOR] corsConfig 주입 방법 변경
WithFortuna Jun 20, 2025
cc57295
Merge branch 'develop' of github.com:suyoungSwim/spring-vote-21st int…
WithFortuna Jun 20, 2025
5a2c987
[FEAT] 쿠키 송수신 테스트 컨트롤러
WithFortuna Jun 20, 2025
ac07769
[FEAT] 쿠키 송수신 테스트 컨트롤러 허용 security 경로
WithFortuna Jun 20, 2025
db74249
[FEAT 테스트컨트롤러 다시 삭제
WithFortuna Jun 20, 2025
276283f
[FIX]swaggerconfig 서버 주소 변경
WithFortuna Jun 23, 2025
b6d7acc
[FIX] swaggerConfig 경로
WithFortuna Jun 23, 2025
0183fa0
[FIX] swagger 서버 경로 수정
WithFortuna Jun 23, 2025
5931d15
[FIX] Update CorsConfig.java
WithFortuna Jun 23, 2025
9dcdf45
Update CorsConfig.java
WithFortuna Jun 23, 2025
7d2daba
Update CorsConfig.java
WithFortuna Jun 23, 2025
600d16b
[FIX] 선거 모두 삭제
WithFortuna Jun 23, 2025
8ddc97d
Merge pull request #51 from suyoungSwim/feature/#50-fix-election-dele…
WithFortuna Jun 23, 2025
25d94ab
[STYLE]Update application-docker.yml
WithFortuna Jun 23, 2025
40c6d25
[FEAT] 섹션별 선거 조회 추가
WithFortuna Jun 23, 2025
6551001
Merge branch 'develop' of github.com:suyoungSwim/spring-vote-21st int…
WithFortuna Jun 23, 2025
04cfde2
Merge pull request #53 from suyoungSwim/feature/#52-election-by-section
WithFortuna Jun 23, 2025
3f02833
[CI] 깃액션 워크플로우 수정
WithFortuna Jun 23, 2025
d72a24d
Revert "[FEAT]#52 선거 조회 엔드포인트 추가"
WithFortuna Jun 23, 2025
2039cc0
Merge pull request #54 from suyoungSwim/revert-53-feature/#52-electio…
WithFortuna Jun 23, 2025
a7bc6e0
Merge branch 'develop' of github.com:suyoungSwim/spring-vote-21st int…
WithFortuna Jun 23, 2025
532ef20
Revert "Revert "[FEAT]#52 선거 조회 엔드포인트 추가""
WithFortuna Jun 23, 2025
8964e7d
Merge pull request #55 from suyoungSwim/feature/#52-election-by-section
WithFortuna Jun 23, 2025
827ef71
[CHORE]Update application-docker.yml
WithFortuna Jun 23, 2025
00e4912
[FEAT] 투표여부 조회 쿼리 - 비관적 락
WithFortuna Jun 26, 2025
51a3e23
[FEAT] 투표 엔드포인트 DTO 수정
WithFortuna Jun 26, 2025
f5598d6
Merge branch 'develop' of github.com:suyoungSwim/spring-vote-21st int…
WithFortuna Jun 26, 2025
c0bc4d2
Merge pull request #57 from suyoungSwim/refactor/#56-vote-memberId
WithFortuna Jun 26, 2025
ae0a325
[CI] 깃액션 워크플로우 수정
WithFortuna Jun 26, 2025
f3262c9
Merge branch 'develop' of github.com:suyoungSwim/spring-vote-21st int…
WithFortuna Jun 26, 2025
0d7de88
[FIX] 투표 조회 쿼리 수정
WithFortuna Jun 26, 2025
8cedcd9
[REFACTOR] 팀 이름 변경
WithFortuna Jun 27, 2025
c96f3bc
[FIX] CICD시 도커 이미지 정리
WithFortuna Jun 27, 2025
c32fab0
Merge pull request #59 from suyoungSwim/fix/#58-clean-docker-image
WithFortuna Jun 27, 2025
23f5d93
[CHORE] application.yml 수정
WithFortuna Jun 27, 2025
0916dec
[CHORE] application-docker.yml 수정
WithFortuna Jun 27, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# 빌드 아웃풋/임시파일/불필요한 것들 무시
*.class
*.jar
*.war
*.log
*.iml
*.swp
*.swo
*~
.DS_Store

# IDE/빌드 시스템 폴더
.gradle/
.idea/
.vscode/
build/
out/
target/

# Git
.git
.gitignore

do
61 changes: 61 additions & 0 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
name: CI/CD Deploy

on:
push:
branches: [develop] #dev에 push 될 때 마다 실행

jobs:
build-and-deploy:
runs-on: ubuntu-latest #GitHub에서 제공하는 ubuntu-latest에서 실행

steps:
- name: Checkout repository #깃허브 저장소의 코드를 runner로 가져옴
uses: actions/checkout@v4

- name: Set up Docker Buildx #도커 setup
uses: docker/setup-buildx-action@v3

- name: Login to DockerHub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}

- name: Build and push Docker image
uses: docker/build-push-action@v5
with:
context: .
push: true
tags: ${{ secrets.DOCKERHUB_USERNAME }}/vote-server:latest

- name: Deploy to EC2 via SSH
uses: appleboy/[email protected]
with:
host: ${{ secrets.EC2_HOST }}
username: ${{ secrets.EC2_USER }}
key: ${{ secrets.EC2_SSH_KEY }}
script: |
set -e
echo "Stopping containers..."
sudo docker-compose down
CONTAINER_ID=$(sudo docker ps -qf "ancestor=${{ secrets.DOCKERHUB_USERNAME }}/vote-server:latest")

if [ -n "$CONTAINER_ID" ]; then
USED_ID=$(sudo docker inspect "$CONTAINER_ID" --format='{{.Image}}')
else
USED_ID="none"
fi

echo "Removing unused vote-server images..."
for IMG_ID in $(sudo docker images ${{ secrets.DOCKERHUB_USERNAME }}/vote-server -q); do
if [ "$IMG_ID" != "$USED_ID" ]; then
echo "Removing unused image: $IMG_ID"
sudo docker rmi $IMG_ID || true
fi
done

echo "Pulling latest image..."
sudo docker pull ${{ secrets.DOCKERHUB_USERNAME }}/vote-server:latest

echo "Starting up containers..."
sudo docker-compose up -d
1 change: 1 addition & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ WORKDIR /app
#현재 디렉토리(소스코드 전체)를 컨테이너의 /app으로 복사.
#도커파일 .과 ..은 각각 내 컴퓨터의 현재 디렉토리, 컨테이너의 현재 학업 디렉토리를 의미한다고 한다.
COPY . .
RUN head -20 src/main/java/com/ceos/spring_vote_21st/security/config/SecurityConfig.java

#gradle로 프로젝트 빌드 => JAR 파일 생성
RUN gradle clean build -x test
Expand Down
5 changes: 5 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,13 @@ dependencies {
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'org.springframework.security:spring-security-test'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
//swagger
implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.7.0'

// dotenv
testImplementation 'io.github.cdimascio:dotenv-java:3.0.0'
implementation 'com.h2database:h2'

}

tasks.named('test') {
Expand Down
17 changes: 17 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,14 @@ services: #컨테이너들 정의. 여기선 app(server)와 db
SPRING_DATASOURCE_USERNAME: ${SPRING_DATASOURCE_USERNAME}
SPRING_DATASOURCE_PASSWORD: ${SPRING_DATASOURCE_PASSWORD} #db 비밀번호
SERVER_PORT: ${SERVER_PORT}
REDIS_HOST: ${REDIS_HOST} # redis 컨테이너 이름을 host로 사용 (Docker 네트워크상에서 가능)
REDIS_PORT: ${REDIS_PORT}
JWT_SECRET_KEY: ${JWT_SECRET_KEY}
JWT_ACCESS_TOKEN_EXPIRATION: ${JWT_ACCESS_TOKEN_EXPIRATION}
JWT_REFRESH_TOKEN_EXPIRATION: ${JWT_REFRESH_TOKEN_EXPIRATION}
depends_on: # db가 먼저 실행되어야 app이 실행됨
- db
- redis

db: #컨테이너 이름 db
image: mysql:8.0 #공식 mysql:8.0 이미지를 다운받아 컨테이너에서 바로 띄움
Expand All @@ -31,8 +37,19 @@ services: #컨테이너들 정의. 여기선 app(server)와 db
volumes: #DB 데이터가 컨테이너 재시작/삭제되어도 날아가지 않게 호스트 pc에 저장
- mysql_data:/var/lib/mysql

redis:
image: redis:7.2-alpine # 공식 경량 이미지 추천
container_name: vote-redis
ports:
- "${REDIS_HOST_PORT}:${REDIS_PORT}" # 필요에 따라 외부 노출 (보통은 내부 연결만 해도 충분)
volumes:
- redis_data:/data # Redis 데이터 영속화 (optional)
restart: unless-stopped


volumes:
mysql_data:
redis_data:

#환경변수 흐름
#.env → docker-compose.yml → application-docker.yaml
Binary file modified gradle/wrapper/gradle-wrapper.jar
Binary file not shown.
2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
Expand Down
4 changes: 2 additions & 2 deletions gradlew
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ case "$( uname )" in #(
NONSTOP* ) nonstop=true ;;
esac

CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
CLASSPATH="\\\"\\\""


# Determine the Java command to use to start the JVM.
Expand Down Expand Up @@ -213,7 +213,7 @@ DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \
-classpath "$CLASSPATH" \
org.gradle.wrapper.GradleWrapperMain \
-jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \
"$@"

# Stop when "xargs" is not available.
Expand Down
4 changes: 2 additions & 2 deletions gradlew.bat
Original file line number Diff line number Diff line change
Expand Up @@ -70,11 +70,11 @@ goto fail
:execute
@rem Setup the command line

set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
set CLASSPATH=


@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %*

:end
@rem End local scope for the variables with windows NT shell
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
package com.ceos.spring_vote_21st.admin.controller;

import com.ceos.spring_vote_21st.global.response.dto.CommonResponse;
import com.ceos.spring_vote_21st.member.service.MemberService;
import com.ceos.spring_vote_21st.vote.service.ElectionService;
import com.ceos.spring_vote_21st.vote.web.dto.request.CandidateAddRequestDTO;
import com.ceos.spring_vote_21st.vote.web.dto.request.CandidateModifyRequestDTO;
import com.ceos.spring_vote_21st.vote.web.dto.request.ElectionCreateRequestDTO;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

@RequestMapping("/api/v1/admin")
@RequiredArgsConstructor
@RestController
public class AdminController {
private final MemberService memberService;
private final ElectionService electionService;

/**
* Member
* */
@DeleteMapping("/members/{memberId}")
public ResponseEntity<Void> delete(@PathVariable Long memberId) {
memberService.deleteMember(memberId);
return ResponseEntity.noContent().build(); // ResponseEntity.noContent()는 응답 바디를 아예 쓰지않음.(wrapping은 되지만 클라이언트는 바디를 안받는다)
}

@DeleteMapping("/members")
public ResponseEntity<Void> deleteAll() {
memberService.deleteAll();
return ResponseEntity.noContent().build();
}

/**
* Election
*/
@PostMapping("/elections")
public ResponseEntity<CommonResponse<Long>> createElection(@RequestBody ElectionCreateRequestDTO dto) {
Long id = electionService.createElection(dto);
return ResponseEntity.ok(CommonResponse.success(id));
}


@DeleteMapping("/elections/{electionId}")
public ResponseEntity<Void> deleteElection(@PathVariable Long electionId) {
electionService.deleteElection(electionId);
return ResponseEntity.noContent().build();
}

@DeleteMapping("/elections")
public ResponseEntity<Void> deleteAllElections() {
electionService.deleteAll();
return ResponseEntity.noContent().build();
}

/**
* Candidate
*/

// 후보 추가
@PostMapping("/elections/{electionId}/candidates")
public ResponseEntity<CommonResponse<Long>> addCandidate(
@RequestBody CandidateAddRequestDTO dto) {
Long id = electionService.addCandidate(dto);
return ResponseEntity.ok(CommonResponse.success(id));
}

// 후보 정보 수정
@PutMapping("/elections/{electionId}/candidates")
public ResponseEntity<CommonResponse<Long>> modifyCandidate(
@RequestBody CandidateModifyRequestDTO dto) {
Long id = electionService.modifyCandidate(dto);
return ResponseEntity.ok(CommonResponse.success(id));
}

// delete
@DeleteMapping("/elections/{electionId}/candidates/{candidateId}")
public ResponseEntity<CommonResponse<?>> deleteCandidate(@PathVariable Long electionId, @PathVariable Long candidateId) {
electionService.deleteCandidate(electionId, candidateId);

return ResponseEntity.ok(CommonResponse.success(null));
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,14 @@
@RestController
public class HealthCheckController {



@GetMapping("/health")
public String healthCheck() {
return "OK";
}
@GetMapping("/health/new")
public String healthCheckNew() {
return "OK2";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package com.ceos.spring_vote_21st.global.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;

import java.util.List;

/**
* CORS 전역 설정
* - Authorization 헤더를 클라이언트에 노출하여 Access Token 볼 수 있도록 지원함
*/
@Configuration
public class CorsConfig {

@Bean
public CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration config = new CorsConfiguration();
// 허용할 오리진 패턴 (필요 시 특정 도메인만 허용)
config.setAllowedOriginPatterns(List.of(
"http://localhost:3000",
"https://next-vote-21th.vercel.app",
"https://hanihome-fe-test-gnos-projects-ab4a3758.vercel.app",
"https://hanihome-vote.shop",
"https://hanihome-fe-test.vercel.app"
));
// 허용할 HTTP 메서드
config.setAllowedMethods(List.of("GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS"));
// 허용할 요청 헤더
config.setAllowedHeaders(List.of("*"));
config.setExposedHeaders(List.of("Authorization")); // 클라이언트가 AccessToken 접근 가능하도록 지원
// 쿠키 전송 허용 여부
config.setAllowCredentials(true);

UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", config); // 모든 URI에 대해서
return source;
}
/*
*
@Bean
@Profile("local") // 로컬 프로필
public CorsConfigurationSource devCorsConfig() {
CorsConfiguration c = new CorsConfiguration();
c.setAllowedOriginPatterns(List.of(
"http://localhost:*",
"https://*.ngrok-free.app"
));
c.setAllowCredentials(false);
applyCommon(c);
return source(c);
}

@Bean
@Profile("prod") // 운영 프로필
public CorsConfigurationSource prodCorsConfig() {
CorsConfiguration c = new CorsConfiguration();
c.setAllowedOriginPatterns(List.of(
"https://web.example.com",
"https://admin.example.com"
));
c.setAllowCredentials(true);
applyCommon(c);
return source(c);
}
*/
}
Loading