Skip to content

Commit 82e42e0

Browse files
authored
Merge pull request #46 from prgrms-web-devcourse-final-project/feat/#26/create-auth-domain-mvp
[BE/feat] auth 도메인 1차 제작
2 parents 7e76365 + 54e5936 commit 82e42e0

35 files changed

+1358
-98
lines changed

.github/workflows/ci.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ jobs:
1010
build:
1111
runs-on: ubuntu-latest
1212

13+
env:
14+
JWT_SECRET: ${{ secrets.JWT_SECRET }}
15+
1316
steps:
1417
- name: Checkout code
1518
uses: actions/checkout@v4

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,5 +41,6 @@ out/
4141

4242
###custom###
4343
application-secret.yml
44+
.env
4445
db_dev.mv.db
4546
db_dev.trace.db

build.gradle

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,13 @@ dependencies {
4141
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
4242
implementation("org.springdoc:springdoc-openapi-starter-webmvc-ui:2.8.13")
4343
runtimeOnly("com.mysql:mysql-connector-j")
44+
45+
// JWT 라이브러리
46+
implementation("io.jsonwebtoken:jjwt-api:0.12.6")
47+
runtimeOnly("io.jsonwebtoken:jjwt-impl:0.12.6")
48+
runtimeOnly("io.jsonwebtoken:jjwt-jackson:0.12.6")
49+
implementation("com.fasterxml.jackson.datatype:jackson-datatype-jsr310")
50+
implementation("com.fasterxml.jackson.module:jackson-module-kotlin")
4451
}
4552

4653
tasks.named('test') {

src/main/java/back/kalender/KalenderApplication.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,12 @@
22

33
import org.springframework.boot.SpringApplication;
44
import org.springframework.boot.autoconfigure.SpringBootApplication;
5+
import org.springframework.boot.context.properties.ConfigurationPropertiesScan;
56
import org.springframework.scheduling.annotation.EnableScheduling;
67

78
@SpringBootApplication
89
@EnableScheduling
10+
@ConfigurationPropertiesScan
911
public class KalenderApplication {
1012

1113
public static void main(String[] args) {

src/main/java/back/kalender/domain/auth/controller/UserAuthController.java

Lines changed: 257 additions & 60 deletions
Large diffs are not rendered by default.

src/main/java/back/kalender/domain/auth/entity/.gitkeep

Whitespace-only changes.
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
package back.kalender.domain.auth.entity;
2+
3+
import back.kalender.global.common.entity.BaseEntity;
4+
import jakarta.persistence.*;
5+
import lombok.AccessLevel;
6+
import lombok.Getter;
7+
import lombok.NoArgsConstructor;
8+
9+
import java.time.LocalDateTime;
10+
11+
// 이메일 인증
12+
@Entity
13+
@Getter
14+
@NoArgsConstructor(access = AccessLevel.PROTECTED)
15+
@Table(
16+
name = "email_verifications",
17+
indexes = {
18+
@Index(name = "idx_user_id", columnList = "userId"),
19+
@Index(name = "idx_code", columnList = "code")
20+
}
21+
)
22+
public class EmailVerification extends BaseEntity {
23+
24+
private static final int DEFAULT_EXPIRY_MINUTES = 5;
25+
26+
@Column(nullable = false)
27+
private Long userId;
28+
29+
@Column(nullable = false, length = 50)
30+
private String code;
31+
32+
private boolean used;
33+
34+
@Column(nullable = false)
35+
private LocalDateTime expiredAt;
36+
37+
public static EmailVerification create(Long userId, String code) {
38+
return create(userId, code, DEFAULT_EXPIRY_MINUTES);
39+
}
40+
41+
public static EmailVerification create(Long userId, String code, int expiryMinutes) {
42+
EmailVerification ev = new EmailVerification();
43+
ev.userId = userId;
44+
ev.code = code;
45+
ev.used = false;
46+
ev.expiredAt = LocalDateTime.now().plusMinutes(expiryMinutes);
47+
return ev;
48+
}
49+
50+
public void markUsed() {
51+
this.used = true;
52+
}
53+
54+
public boolean isExpired() {
55+
return expiredAt.isBefore(LocalDateTime.now());
56+
}
57+
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
package back.kalender.domain.auth.entity;
2+
3+
import back.kalender.global.common.entity.BaseEntity;
4+
import jakarta.persistence.*;
5+
import lombok.AccessLevel;
6+
import lombok.Getter;
7+
import lombok.NoArgsConstructor;
8+
9+
import java.time.LocalDateTime;
10+
11+
// 비밀번호 변경
12+
@Entity
13+
@Getter
14+
@NoArgsConstructor(access = AccessLevel.PROTECTED)
15+
@Table(
16+
name = "password_reset_tokens",
17+
indexes = {
18+
@Index(name = "idx_password_user_id", columnList = "userId"),
19+
@Index(name = "idx_password_token", columnList = "token")
20+
}
21+
)
22+
public class PasswordResetToken extends BaseEntity {
23+
24+
private static final int DEFAULT_EXPIRY_MINUTES = 5;
25+
26+
@Column(nullable = false)
27+
private Long userId;
28+
29+
@Column(nullable = false, length = 500)
30+
private String token;
31+
32+
private boolean used;
33+
34+
@Column(nullable = false)
35+
private LocalDateTime expiredAt;
36+
37+
public static PasswordResetToken create(Long userId, String code) {
38+
return create(userId, code, DEFAULT_EXPIRY_MINUTES);
39+
}
40+
41+
public static PasswordResetToken create(Long userId, String code, int expiryMinutes) {
42+
PasswordResetToken token = new PasswordResetToken();
43+
token.userId = userId;
44+
token.token = code;
45+
token.used = false;
46+
token.expiredAt = LocalDateTime.now().plusMinutes(expiryMinutes);
47+
return token;
48+
}
49+
50+
public void markUsed() {
51+
this.used = true;
52+
}
53+
54+
public boolean isExpired() {
55+
return expiredAt.isBefore(LocalDateTime.now());
56+
}
57+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package back.kalender.domain.auth.entity;
2+
3+
import back.kalender.global.common.entity.BaseEntity;
4+
import jakarta.persistence.*;
5+
import lombok.AccessLevel;
6+
import lombok.Getter;
7+
import lombok.NoArgsConstructor;
8+
9+
import java.time.LocalDateTime;
10+
11+
// 리프레시 토큰
12+
@Entity
13+
@Getter
14+
@NoArgsConstructor(access = AccessLevel.PROTECTED)
15+
@Table(
16+
name = "refresh_tokens",
17+
indexes = {
18+
@Index(name = "idx_refresh_user_id", columnList = "userId"),
19+
@Index(name = "idx_refresh_token", columnList = "token")
20+
}
21+
)
22+
public class RefreshToken extends BaseEntity {
23+
24+
@Column(nullable = false)
25+
private Long userId;
26+
27+
@Column(nullable = false, length = 1000)
28+
private String token;
29+
30+
@Column(nullable = false)
31+
private LocalDateTime expiredAt;
32+
33+
public static RefreshToken create(Long userId, String token, long ttlDays) {
34+
RefreshToken rt = new RefreshToken();
35+
rt.userId = userId;
36+
rt.token = token;
37+
rt.expiredAt = LocalDateTime.now().plusDays(ttlDays);
38+
return rt;
39+
}
40+
41+
public boolean isExpired() {
42+
return expiredAt.isBefore(LocalDateTime.now());
43+
}
44+
45+
}

src/main/java/back/kalender/domain/auth/repository/.gitkeep

Whitespace-only changes.

0 commit comments

Comments
 (0)