dn-react-router-toolkit 0.2.0 → 0.2.1
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.
- package/dist/auth/auth_repository.d.mts +7 -5
- package/dist/auth/auth_repository.d.ts +7 -5
- package/dist/auth/auth_service.d.mts +1 -1
- package/dist/auth/auth_service.d.ts +1 -1
- package/dist/auth/auth_service.js +1 -1
- package/dist/auth/auth_service.mjs +1 -1
- package/dist/auth/client/provider.d.mts +3 -0
- package/dist/auth/client/provider.d.ts +3 -0
- package/dist/auth/client/provider.js +17 -2
- package/dist/auth/client/provider.mjs +17 -2
- package/dist/auth/handlers/login.js +1 -1
- package/dist/auth/handlers/login.mjs +1 -1
- package/dist/auth/handlers/request_password_reset.d.mts +10 -0
- package/dist/auth/handlers/request_password_reset.d.ts +10 -0
- package/dist/auth/handlers/request_password_reset.js +87 -0
- package/dist/auth/handlers/request_password_reset.mjs +60 -0
- package/dist/auth/handlers/reset_password.d.mts +10 -0
- package/dist/auth/handlers/reset_password.d.ts +10 -0
- package/dist/auth/handlers/reset_password.js +88 -0
- package/dist/auth/handlers/reset_password.mjs +61 -0
- package/dist/auth/handlers/signup.js +17 -5
- package/dist/auth/handlers/signup.mjs +17 -5
- package/dist/auth/password_recovery.d.mts +34 -0
- package/dist/auth/password_recovery.d.ts +34 -0
- package/dist/auth/password_recovery.js +169 -0
- package/dist/auth/password_recovery.mjs +134 -0
- package/dist/route/api.d.mts +3 -1
- package/dist/route/api.d.ts +3 -1
- package/dist/route/api.js +48 -6
- package/dist/route/api.mjs +48 -6
- package/package.json +3 -1
|
@@ -1,8 +1,15 @@
|
|
|
1
1
|
interface AuthRepository<TFile = unknown> {
|
|
2
2
|
findCredentialById(id: string): Promise<{
|
|
3
|
+
id: string;
|
|
3
4
|
password: string;
|
|
4
5
|
userId: string;
|
|
5
6
|
} | undefined>;
|
|
7
|
+
createCredential(params: {
|
|
8
|
+
id: string;
|
|
9
|
+
password: string;
|
|
10
|
+
userId: string;
|
|
11
|
+
}): Promise<void>;
|
|
12
|
+
updatePassword(id: string, hashedPassword: string): Promise<void>;
|
|
6
13
|
findUserById(userId: string): Promise<{
|
|
7
14
|
id: string;
|
|
8
15
|
role: string;
|
|
@@ -29,11 +36,6 @@ interface AuthRepository<TFile = unknown> {
|
|
|
29
36
|
provider: string;
|
|
30
37
|
userId: string;
|
|
31
38
|
}): Promise<void>;
|
|
32
|
-
createCredential(params: {
|
|
33
|
-
id: string;
|
|
34
|
-
password: string;
|
|
35
|
-
userId: string;
|
|
36
|
-
}): Promise<void>;
|
|
37
39
|
}
|
|
38
40
|
|
|
39
41
|
export type { AuthRepository };
|
|
@@ -1,8 +1,15 @@
|
|
|
1
1
|
interface AuthRepository<TFile = unknown> {
|
|
2
2
|
findCredentialById(id: string): Promise<{
|
|
3
|
+
id: string;
|
|
3
4
|
password: string;
|
|
4
5
|
userId: string;
|
|
5
6
|
} | undefined>;
|
|
7
|
+
createCredential(params: {
|
|
8
|
+
id: string;
|
|
9
|
+
password: string;
|
|
10
|
+
userId: string;
|
|
11
|
+
}): Promise<void>;
|
|
12
|
+
updatePassword(id: string, hashedPassword: string): Promise<void>;
|
|
6
13
|
findUserById(userId: string): Promise<{
|
|
7
14
|
id: string;
|
|
8
15
|
role: string;
|
|
@@ -29,11 +36,6 @@ interface AuthRepository<TFile = unknown> {
|
|
|
29
36
|
provider: string;
|
|
30
37
|
userId: string;
|
|
31
38
|
}): Promise<void>;
|
|
32
|
-
createCredential(params: {
|
|
33
|
-
id: string;
|
|
34
|
-
password: string;
|
|
35
|
-
userId: string;
|
|
36
|
-
}): Promise<void>;
|
|
37
39
|
}
|
|
38
40
|
|
|
39
41
|
export type { AuthRepository };
|
|
@@ -24,7 +24,7 @@ declare class AuthService<TFile = unknown> {
|
|
|
24
24
|
getAccessTokenFromCookies(request: Request): Promise<any>;
|
|
25
25
|
getRefreshTokenFromCookies(request: Request): Promise<any>;
|
|
26
26
|
refresh(request: Request): Promise<jose.JWTPayload | undefined>;
|
|
27
|
-
|
|
27
|
+
login({ id, password }: {
|
|
28
28
|
id: string;
|
|
29
29
|
password: string;
|
|
30
30
|
}): Promise<{
|
|
@@ -24,7 +24,7 @@ declare class AuthService<TFile = unknown> {
|
|
|
24
24
|
getAccessTokenFromCookies(request: Request): Promise<any>;
|
|
25
25
|
getRefreshTokenFromCookies(request: Request): Promise<any>;
|
|
26
26
|
refresh(request: Request): Promise<jose.JWTPayload | undefined>;
|
|
27
|
-
|
|
27
|
+
login({ id, password }: {
|
|
28
28
|
id: string;
|
|
29
29
|
password: string;
|
|
30
30
|
}): Promise<{
|
|
@@ -117,7 +117,7 @@ var AuthService = class {
|
|
|
117
117
|
}
|
|
118
118
|
}
|
|
119
119
|
}
|
|
120
|
-
async
|
|
120
|
+
async login({ id, password }) {
|
|
121
121
|
const credential = await this.authRepository.findCredentialById(id);
|
|
122
122
|
if (!credential) {
|
|
123
123
|
throw Error("\uC544\uC774\uB514 \uB610\uB294 \uBE44\uBC00\uBC88\uD638\uAC00 \uD2C0\uB838\uC2B5\uB2C8\uB2E4.");
|
|
@@ -79,7 +79,7 @@ var AuthService = class {
|
|
|
79
79
|
}
|
|
80
80
|
}
|
|
81
81
|
}
|
|
82
|
-
async
|
|
82
|
+
async login({ id, password }) {
|
|
83
83
|
const credential = await this.authRepository.findCredentialById(id);
|
|
84
84
|
if (!credential) {
|
|
85
85
|
throw Error("\uC544\uC774\uB514 \uB610\uB294 \uBE44\uBC00\uBC88\uD638\uAC00 \uD2C0\uB838\uC2B5\uB2C8\uB2E4.");
|
|
@@ -7,6 +7,9 @@ type AuthContextValue = {
|
|
|
7
7
|
login: (id: string, password: string) => Promise<void>;
|
|
8
8
|
loginWithGoogle: (redirectUrl?: string) => Promise<void>;
|
|
9
9
|
logout: () => Promise<void>;
|
|
10
|
+
signup: (email: string, password: string, passwordConfirm: string) => Promise<{
|
|
11
|
+
userId: string;
|
|
12
|
+
}>;
|
|
10
13
|
requestResetPassword: (email: string) => Promise<boolean>;
|
|
11
14
|
resetPassword: (token: string, password: string, passwordConfirm: string) => Promise<boolean>;
|
|
12
15
|
};
|
|
@@ -7,6 +7,9 @@ type AuthContextValue = {
|
|
|
7
7
|
login: (id: string, password: string) => Promise<void>;
|
|
8
8
|
loginWithGoogle: (redirectUrl?: string) => Promise<void>;
|
|
9
9
|
logout: () => Promise<void>;
|
|
10
|
+
signup: (email: string, password: string, passwordConfirm: string) => Promise<{
|
|
11
|
+
userId: string;
|
|
12
|
+
}>;
|
|
10
13
|
requestResetPassword: (email: string) => Promise<boolean>;
|
|
11
14
|
resetPassword: (token: string, password: string, passwordConfirm: string) => Promise<boolean>;
|
|
12
15
|
};
|
|
@@ -90,8 +90,22 @@ function AuthProvider({ children, googleAuth }) {
|
|
|
90
90
|
alert(message);
|
|
91
91
|
}
|
|
92
92
|
};
|
|
93
|
+
const signup = async (email, password, passwordConfirm) => {
|
|
94
|
+
const response = await fetch("/api/auth/signup", {
|
|
95
|
+
method: "POST",
|
|
96
|
+
headers: {
|
|
97
|
+
"Content-Type": "application/json"
|
|
98
|
+
},
|
|
99
|
+
body: JSON.stringify({ email, password, passwordConfirm })
|
|
100
|
+
});
|
|
101
|
+
if (!response.ok) {
|
|
102
|
+
const { message } = await response.json();
|
|
103
|
+
throw new Error(message);
|
|
104
|
+
}
|
|
105
|
+
return response.json();
|
|
106
|
+
};
|
|
93
107
|
const requestResetPassword = async (email) => {
|
|
94
|
-
const response = await fetch("/api/
|
|
108
|
+
const response = await fetch("/api/auth/request-password-reset", {
|
|
95
109
|
method: "POST",
|
|
96
110
|
headers: {
|
|
97
111
|
"Content-Type": "application/json"
|
|
@@ -106,7 +120,7 @@ function AuthProvider({ children, googleAuth }) {
|
|
|
106
120
|
return true;
|
|
107
121
|
};
|
|
108
122
|
const resetPassword = async (token, password, passwordConfirm) => {
|
|
109
|
-
const response = await fetch("/api/reset-password", {
|
|
123
|
+
const response = await fetch("/api/auth/reset-password", {
|
|
110
124
|
method: "POST",
|
|
111
125
|
headers: {
|
|
112
126
|
"Content-Type": "application/json"
|
|
@@ -125,6 +139,7 @@ function AuthProvider({ children, googleAuth }) {
|
|
|
125
139
|
login,
|
|
126
140
|
logout,
|
|
127
141
|
loginWithGoogle,
|
|
142
|
+
signup,
|
|
128
143
|
requestResetPassword,
|
|
129
144
|
resetPassword
|
|
130
145
|
};
|
|
@@ -54,8 +54,22 @@ function AuthProvider({ children, googleAuth }) {
|
|
|
54
54
|
alert(message);
|
|
55
55
|
}
|
|
56
56
|
};
|
|
57
|
+
const signup = async (email, password, passwordConfirm) => {
|
|
58
|
+
const response = await fetch("/api/auth/signup", {
|
|
59
|
+
method: "POST",
|
|
60
|
+
headers: {
|
|
61
|
+
"Content-Type": "application/json"
|
|
62
|
+
},
|
|
63
|
+
body: JSON.stringify({ email, password, passwordConfirm })
|
|
64
|
+
});
|
|
65
|
+
if (!response.ok) {
|
|
66
|
+
const { message } = await response.json();
|
|
67
|
+
throw new Error(message);
|
|
68
|
+
}
|
|
69
|
+
return response.json();
|
|
70
|
+
};
|
|
57
71
|
const requestResetPassword = async (email) => {
|
|
58
|
-
const response = await fetch("/api/
|
|
72
|
+
const response = await fetch("/api/auth/request-password-reset", {
|
|
59
73
|
method: "POST",
|
|
60
74
|
headers: {
|
|
61
75
|
"Content-Type": "application/json"
|
|
@@ -70,7 +84,7 @@ function AuthProvider({ children, googleAuth }) {
|
|
|
70
84
|
return true;
|
|
71
85
|
};
|
|
72
86
|
const resetPassword = async (token, password, passwordConfirm) => {
|
|
73
|
-
const response = await fetch("/api/reset-password", {
|
|
87
|
+
const response = await fetch("/api/auth/reset-password", {
|
|
74
88
|
method: "POST",
|
|
75
89
|
headers: {
|
|
76
90
|
"Content-Type": "application/json"
|
|
@@ -89,6 +103,7 @@ function AuthProvider({ children, googleAuth }) {
|
|
|
89
103
|
login,
|
|
90
104
|
logout,
|
|
91
105
|
loginWithGoogle,
|
|
106
|
+
signup,
|
|
92
107
|
requestResetPassword,
|
|
93
108
|
resetPassword
|
|
94
109
|
};
|
|
@@ -74,7 +74,7 @@ var loginHandler = async (request, {
|
|
|
74
74
|
}) => {
|
|
75
75
|
const { id, password } = await request.json();
|
|
76
76
|
try {
|
|
77
|
-
const { accessToken, refreshToken } = await authService.
|
|
77
|
+
const { accessToken, refreshToken } = await authService.login({
|
|
78
78
|
id,
|
|
79
79
|
password
|
|
80
80
|
});
|
|
@@ -48,7 +48,7 @@ var loginHandler = async (request, {
|
|
|
48
48
|
}) => {
|
|
49
49
|
const { id, password } = await request.json();
|
|
50
50
|
try {
|
|
51
|
-
const { accessToken, refreshToken } = await authService.
|
|
51
|
+
const { accessToken, refreshToken } = await authService.login({
|
|
52
52
|
id,
|
|
53
53
|
password
|
|
54
54
|
});
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { PasswordRecoveryService } from '../password_recovery.mjs';
|
|
2
|
+
import '../auth_repository.mjs';
|
|
3
|
+
import '../jwt_manager.mjs';
|
|
4
|
+
import 'jose';
|
|
5
|
+
|
|
6
|
+
declare const requestPasswordResetHandler: (request: Request, { passwordRecoveryService, }: {
|
|
7
|
+
passwordRecoveryService: PasswordRecoveryService;
|
|
8
|
+
}) => Promise<Response>;
|
|
9
|
+
|
|
10
|
+
export { requestPasswordResetHandler };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { PasswordRecoveryService } from '../password_recovery.js';
|
|
2
|
+
import '../auth_repository.js';
|
|
3
|
+
import '../jwt_manager.js';
|
|
4
|
+
import 'jose';
|
|
5
|
+
|
|
6
|
+
declare const requestPasswordResetHandler: (request: Request, { passwordRecoveryService, }: {
|
|
7
|
+
passwordRecoveryService: PasswordRecoveryService;
|
|
8
|
+
}) => Promise<Response>;
|
|
9
|
+
|
|
10
|
+
export { requestPasswordResetHandler };
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/auth/handlers/request_password_reset.ts
|
|
21
|
+
var request_password_reset_exports = {};
|
|
22
|
+
__export(request_password_reset_exports, {
|
|
23
|
+
requestPasswordResetHandler: () => requestPasswordResetHandler
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(request_password_reset_exports);
|
|
26
|
+
|
|
27
|
+
// src/http/response.ts
|
|
28
|
+
var createJsonResponse = (status) => {
|
|
29
|
+
return (data = {}, init) => {
|
|
30
|
+
return Response.json(data, { status, ...init });
|
|
31
|
+
};
|
|
32
|
+
};
|
|
33
|
+
var OK = createJsonResponse(200);
|
|
34
|
+
var CREATED = createJsonResponse(201);
|
|
35
|
+
var ACCEPTED = createJsonResponse(202);
|
|
36
|
+
var createException = (status, defaultMessage = "\uC624\uB958\uAC00 \uBC1C\uC0DD\uD588\uC2B5\uB2C8\uB2E4.") => {
|
|
37
|
+
return (message = defaultMessage, init) => {
|
|
38
|
+
return createJsonResponse(status)({ message }, init);
|
|
39
|
+
};
|
|
40
|
+
};
|
|
41
|
+
var BAD_REQUEST = createException(400, "\uC694\uCCAD\uC774 \uC62C\uBC14\uB974\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.");
|
|
42
|
+
var UNAUTHORIZED = createException(401, "\uC778\uC99D\uC774 \uD544\uC694\uD569\uB2C8\uB2E4.");
|
|
43
|
+
var FORBIDDEN = createException(403, "\uAD8C\uD55C\uC774 \uC5C6\uC2B5\uB2C8\uB2E4.");
|
|
44
|
+
var NOT_FOUND = createException(
|
|
45
|
+
404,
|
|
46
|
+
"\uC694\uCCAD\uD55C \uB9AC\uC18C\uC2A4\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4."
|
|
47
|
+
);
|
|
48
|
+
var METHOD_NOT_ALLOWED = createException(
|
|
49
|
+
405,
|
|
50
|
+
"\uBA54\uC11C\uB4DC\uB97C \uC0AC\uC6A9\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4."
|
|
51
|
+
);
|
|
52
|
+
var NOT_ACCEPTABLE = createException(
|
|
53
|
+
406,
|
|
54
|
+
"\uC694\uCCAD\uD55C \uD615\uC2DD\uC744 \uC0AC\uC6A9\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4."
|
|
55
|
+
);
|
|
56
|
+
var REQUEST_TIMEOUT = createException(
|
|
57
|
+
408,
|
|
58
|
+
"\uC694\uCCAD \uC2DC\uAC04\uC774 \uCD08\uACFC\uB418\uC5C8\uC2B5\uB2C8\uB2E4."
|
|
59
|
+
);
|
|
60
|
+
var CONFLICT = createException(409, "\uC694\uCCAD\uC774 \uCDA9\uB3CC\uD588\uC2B5\uB2C8\uB2E4.");
|
|
61
|
+
var UNPROCESSABLE_ENTITY = createException(
|
|
62
|
+
422,
|
|
63
|
+
"\uCC98\uB9AC\uD560 \uC218 \uC5C6\uB294 \uC5D4\uD2F0\uD2F0\uC785\uB2C8\uB2E4."
|
|
64
|
+
);
|
|
65
|
+
var TOO_MANY_REQUESTS = createException(429, "\uC694\uCCAD\uC774 \uB108\uBB34 \uB9CE\uC2B5\uB2C8\uB2E4.");
|
|
66
|
+
var INTERNAL_SERVER_ERROR = createException(
|
|
67
|
+
500,
|
|
68
|
+
"\uC608\uAE30\uCE58 \uBABB\uD55C \uC624\uB958\uAC00 \uBC1C\uC0DD\uD588\uC2B5\uB2C8\uB2E4."
|
|
69
|
+
);
|
|
70
|
+
|
|
71
|
+
// src/auth/handlers/request_password_reset.ts
|
|
72
|
+
var requestPasswordResetHandler = async (request, {
|
|
73
|
+
passwordRecoveryService
|
|
74
|
+
}) => {
|
|
75
|
+
const { email } = await request.json();
|
|
76
|
+
try {
|
|
77
|
+
await passwordRecoveryService.requestPasswordReset(email);
|
|
78
|
+
return CREATED({ message: "\uBE44\uBC00\uBC88\uD638 \uC7AC\uC124\uC815 \uC774\uBA54\uC77C\uC744 \uC804\uC1A1\uD588\uC2B5\uB2C8\uB2E4." });
|
|
79
|
+
} catch (error) {
|
|
80
|
+
console.error(error);
|
|
81
|
+
return INTERNAL_SERVER_ERROR("\uC774\uBA54\uC77C \uC804\uC1A1\uC5D0 \uC2E4\uD328\uD588\uC2B5\uB2C8\uB2E4.");
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
85
|
+
0 && (module.exports = {
|
|
86
|
+
requestPasswordResetHandler
|
|
87
|
+
});
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
// src/http/response.ts
|
|
2
|
+
var createJsonResponse = (status) => {
|
|
3
|
+
return (data = {}, init) => {
|
|
4
|
+
return Response.json(data, { status, ...init });
|
|
5
|
+
};
|
|
6
|
+
};
|
|
7
|
+
var OK = createJsonResponse(200);
|
|
8
|
+
var CREATED = createJsonResponse(201);
|
|
9
|
+
var ACCEPTED = createJsonResponse(202);
|
|
10
|
+
var createException = (status, defaultMessage = "\uC624\uB958\uAC00 \uBC1C\uC0DD\uD588\uC2B5\uB2C8\uB2E4.") => {
|
|
11
|
+
return (message = defaultMessage, init) => {
|
|
12
|
+
return createJsonResponse(status)({ message }, init);
|
|
13
|
+
};
|
|
14
|
+
};
|
|
15
|
+
var BAD_REQUEST = createException(400, "\uC694\uCCAD\uC774 \uC62C\uBC14\uB974\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.");
|
|
16
|
+
var UNAUTHORIZED = createException(401, "\uC778\uC99D\uC774 \uD544\uC694\uD569\uB2C8\uB2E4.");
|
|
17
|
+
var FORBIDDEN = createException(403, "\uAD8C\uD55C\uC774 \uC5C6\uC2B5\uB2C8\uB2E4.");
|
|
18
|
+
var NOT_FOUND = createException(
|
|
19
|
+
404,
|
|
20
|
+
"\uC694\uCCAD\uD55C \uB9AC\uC18C\uC2A4\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4."
|
|
21
|
+
);
|
|
22
|
+
var METHOD_NOT_ALLOWED = createException(
|
|
23
|
+
405,
|
|
24
|
+
"\uBA54\uC11C\uB4DC\uB97C \uC0AC\uC6A9\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4."
|
|
25
|
+
);
|
|
26
|
+
var NOT_ACCEPTABLE = createException(
|
|
27
|
+
406,
|
|
28
|
+
"\uC694\uCCAD\uD55C \uD615\uC2DD\uC744 \uC0AC\uC6A9\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4."
|
|
29
|
+
);
|
|
30
|
+
var REQUEST_TIMEOUT = createException(
|
|
31
|
+
408,
|
|
32
|
+
"\uC694\uCCAD \uC2DC\uAC04\uC774 \uCD08\uACFC\uB418\uC5C8\uC2B5\uB2C8\uB2E4."
|
|
33
|
+
);
|
|
34
|
+
var CONFLICT = createException(409, "\uC694\uCCAD\uC774 \uCDA9\uB3CC\uD588\uC2B5\uB2C8\uB2E4.");
|
|
35
|
+
var UNPROCESSABLE_ENTITY = createException(
|
|
36
|
+
422,
|
|
37
|
+
"\uCC98\uB9AC\uD560 \uC218 \uC5C6\uB294 \uC5D4\uD2F0\uD2F0\uC785\uB2C8\uB2E4."
|
|
38
|
+
);
|
|
39
|
+
var TOO_MANY_REQUESTS = createException(429, "\uC694\uCCAD\uC774 \uB108\uBB34 \uB9CE\uC2B5\uB2C8\uB2E4.");
|
|
40
|
+
var INTERNAL_SERVER_ERROR = createException(
|
|
41
|
+
500,
|
|
42
|
+
"\uC608\uAE30\uCE58 \uBABB\uD55C \uC624\uB958\uAC00 \uBC1C\uC0DD\uD588\uC2B5\uB2C8\uB2E4."
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
// src/auth/handlers/request_password_reset.ts
|
|
46
|
+
var requestPasswordResetHandler = async (request, {
|
|
47
|
+
passwordRecoveryService
|
|
48
|
+
}) => {
|
|
49
|
+
const { email } = await request.json();
|
|
50
|
+
try {
|
|
51
|
+
await passwordRecoveryService.requestPasswordReset(email);
|
|
52
|
+
return CREATED({ message: "\uBE44\uBC00\uBC88\uD638 \uC7AC\uC124\uC815 \uC774\uBA54\uC77C\uC744 \uC804\uC1A1\uD588\uC2B5\uB2C8\uB2E4." });
|
|
53
|
+
} catch (error) {
|
|
54
|
+
console.error(error);
|
|
55
|
+
return INTERNAL_SERVER_ERROR("\uC774\uBA54\uC77C \uC804\uC1A1\uC5D0 \uC2E4\uD328\uD588\uC2B5\uB2C8\uB2E4.");
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
export {
|
|
59
|
+
requestPasswordResetHandler
|
|
60
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { PasswordRecoveryService } from '../password_recovery.mjs';
|
|
2
|
+
import '../auth_repository.mjs';
|
|
3
|
+
import '../jwt_manager.mjs';
|
|
4
|
+
import 'jose';
|
|
5
|
+
|
|
6
|
+
declare const resetPasswordHandler: (request: Request, { passwordRecoveryService, }: {
|
|
7
|
+
passwordRecoveryService: PasswordRecoveryService;
|
|
8
|
+
}) => Promise<Response>;
|
|
9
|
+
|
|
10
|
+
export { resetPasswordHandler };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { PasswordRecoveryService } from '../password_recovery.js';
|
|
2
|
+
import '../auth_repository.js';
|
|
3
|
+
import '../jwt_manager.js';
|
|
4
|
+
import 'jose';
|
|
5
|
+
|
|
6
|
+
declare const resetPasswordHandler: (request: Request, { passwordRecoveryService, }: {
|
|
7
|
+
passwordRecoveryService: PasswordRecoveryService;
|
|
8
|
+
}) => Promise<Response>;
|
|
9
|
+
|
|
10
|
+
export { resetPasswordHandler };
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/auth/handlers/reset_password.ts
|
|
21
|
+
var reset_password_exports = {};
|
|
22
|
+
__export(reset_password_exports, {
|
|
23
|
+
resetPasswordHandler: () => resetPasswordHandler
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(reset_password_exports);
|
|
26
|
+
|
|
27
|
+
// src/http/response.ts
|
|
28
|
+
var createJsonResponse = (status) => {
|
|
29
|
+
return (data = {}, init) => {
|
|
30
|
+
return Response.json(data, { status, ...init });
|
|
31
|
+
};
|
|
32
|
+
};
|
|
33
|
+
var OK = createJsonResponse(200);
|
|
34
|
+
var CREATED = createJsonResponse(201);
|
|
35
|
+
var ACCEPTED = createJsonResponse(202);
|
|
36
|
+
var NO_CONTENT = (init) => {
|
|
37
|
+
return new Response(null, {
|
|
38
|
+
...init,
|
|
39
|
+
status: 204
|
|
40
|
+
});
|
|
41
|
+
};
|
|
42
|
+
var createException = (status, defaultMessage = "\uC624\uB958\uAC00 \uBC1C\uC0DD\uD588\uC2B5\uB2C8\uB2E4.") => {
|
|
43
|
+
return (message = defaultMessage, init) => {
|
|
44
|
+
return createJsonResponse(status)({ message }, init);
|
|
45
|
+
};
|
|
46
|
+
};
|
|
47
|
+
var BAD_REQUEST = createException(400, "\uC694\uCCAD\uC774 \uC62C\uBC14\uB974\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.");
|
|
48
|
+
var UNAUTHORIZED = createException(401, "\uC778\uC99D\uC774 \uD544\uC694\uD569\uB2C8\uB2E4.");
|
|
49
|
+
var FORBIDDEN = createException(403, "\uAD8C\uD55C\uC774 \uC5C6\uC2B5\uB2C8\uB2E4.");
|
|
50
|
+
var NOT_FOUND = createException(
|
|
51
|
+
404,
|
|
52
|
+
"\uC694\uCCAD\uD55C \uB9AC\uC18C\uC2A4\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4."
|
|
53
|
+
);
|
|
54
|
+
var METHOD_NOT_ALLOWED = createException(
|
|
55
|
+
405,
|
|
56
|
+
"\uBA54\uC11C\uB4DC\uB97C \uC0AC\uC6A9\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4."
|
|
57
|
+
);
|
|
58
|
+
var NOT_ACCEPTABLE = createException(
|
|
59
|
+
406,
|
|
60
|
+
"\uC694\uCCAD\uD55C \uD615\uC2DD\uC744 \uC0AC\uC6A9\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4."
|
|
61
|
+
);
|
|
62
|
+
var REQUEST_TIMEOUT = createException(
|
|
63
|
+
408,
|
|
64
|
+
"\uC694\uCCAD \uC2DC\uAC04\uC774 \uCD08\uACFC\uB418\uC5C8\uC2B5\uB2C8\uB2E4."
|
|
65
|
+
);
|
|
66
|
+
var CONFLICT = createException(409, "\uC694\uCCAD\uC774 \uCDA9\uB3CC\uD588\uC2B5\uB2C8\uB2E4.");
|
|
67
|
+
var UNPROCESSABLE_ENTITY = createException(
|
|
68
|
+
422,
|
|
69
|
+
"\uCC98\uB9AC\uD560 \uC218 \uC5C6\uB294 \uC5D4\uD2F0\uD2F0\uC785\uB2C8\uB2E4."
|
|
70
|
+
);
|
|
71
|
+
var TOO_MANY_REQUESTS = createException(429, "\uC694\uCCAD\uC774 \uB108\uBB34 \uB9CE\uC2B5\uB2C8\uB2E4.");
|
|
72
|
+
var INTERNAL_SERVER_ERROR = createException(
|
|
73
|
+
500,
|
|
74
|
+
"\uC608\uAE30\uCE58 \uBABB\uD55C \uC624\uB958\uAC00 \uBC1C\uC0DD\uD588\uC2B5\uB2C8\uB2E4."
|
|
75
|
+
);
|
|
76
|
+
|
|
77
|
+
// src/auth/handlers/reset_password.ts
|
|
78
|
+
var resetPasswordHandler = async (request, {
|
|
79
|
+
passwordRecoveryService
|
|
80
|
+
}) => {
|
|
81
|
+
const { token, password, passwordConfirm } = await request.json();
|
|
82
|
+
await passwordRecoveryService.resetPassword(token, password, passwordConfirm);
|
|
83
|
+
return NO_CONTENT();
|
|
84
|
+
};
|
|
85
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
86
|
+
0 && (module.exports = {
|
|
87
|
+
resetPasswordHandler
|
|
88
|
+
});
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
// src/http/response.ts
|
|
2
|
+
var createJsonResponse = (status) => {
|
|
3
|
+
return (data = {}, init) => {
|
|
4
|
+
return Response.json(data, { status, ...init });
|
|
5
|
+
};
|
|
6
|
+
};
|
|
7
|
+
var OK = createJsonResponse(200);
|
|
8
|
+
var CREATED = createJsonResponse(201);
|
|
9
|
+
var ACCEPTED = createJsonResponse(202);
|
|
10
|
+
var NO_CONTENT = (init) => {
|
|
11
|
+
return new Response(null, {
|
|
12
|
+
...init,
|
|
13
|
+
status: 204
|
|
14
|
+
});
|
|
15
|
+
};
|
|
16
|
+
var createException = (status, defaultMessage = "\uC624\uB958\uAC00 \uBC1C\uC0DD\uD588\uC2B5\uB2C8\uB2E4.") => {
|
|
17
|
+
return (message = defaultMessage, init) => {
|
|
18
|
+
return createJsonResponse(status)({ message }, init);
|
|
19
|
+
};
|
|
20
|
+
};
|
|
21
|
+
var BAD_REQUEST = createException(400, "\uC694\uCCAD\uC774 \uC62C\uBC14\uB974\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.");
|
|
22
|
+
var UNAUTHORIZED = createException(401, "\uC778\uC99D\uC774 \uD544\uC694\uD569\uB2C8\uB2E4.");
|
|
23
|
+
var FORBIDDEN = createException(403, "\uAD8C\uD55C\uC774 \uC5C6\uC2B5\uB2C8\uB2E4.");
|
|
24
|
+
var NOT_FOUND = createException(
|
|
25
|
+
404,
|
|
26
|
+
"\uC694\uCCAD\uD55C \uB9AC\uC18C\uC2A4\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4."
|
|
27
|
+
);
|
|
28
|
+
var METHOD_NOT_ALLOWED = createException(
|
|
29
|
+
405,
|
|
30
|
+
"\uBA54\uC11C\uB4DC\uB97C \uC0AC\uC6A9\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4."
|
|
31
|
+
);
|
|
32
|
+
var NOT_ACCEPTABLE = createException(
|
|
33
|
+
406,
|
|
34
|
+
"\uC694\uCCAD\uD55C \uD615\uC2DD\uC744 \uC0AC\uC6A9\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4."
|
|
35
|
+
);
|
|
36
|
+
var REQUEST_TIMEOUT = createException(
|
|
37
|
+
408,
|
|
38
|
+
"\uC694\uCCAD \uC2DC\uAC04\uC774 \uCD08\uACFC\uB418\uC5C8\uC2B5\uB2C8\uB2E4."
|
|
39
|
+
);
|
|
40
|
+
var CONFLICT = createException(409, "\uC694\uCCAD\uC774 \uCDA9\uB3CC\uD588\uC2B5\uB2C8\uB2E4.");
|
|
41
|
+
var UNPROCESSABLE_ENTITY = createException(
|
|
42
|
+
422,
|
|
43
|
+
"\uCC98\uB9AC\uD560 \uC218 \uC5C6\uB294 \uC5D4\uD2F0\uD2F0\uC785\uB2C8\uB2E4."
|
|
44
|
+
);
|
|
45
|
+
var TOO_MANY_REQUESTS = createException(429, "\uC694\uCCAD\uC774 \uB108\uBB34 \uB9CE\uC2B5\uB2C8\uB2E4.");
|
|
46
|
+
var INTERNAL_SERVER_ERROR = createException(
|
|
47
|
+
500,
|
|
48
|
+
"\uC608\uAE30\uCE58 \uBABB\uD55C \uC624\uB958\uAC00 \uBC1C\uC0DD\uD588\uC2B5\uB2C8\uB2E4."
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
// src/auth/handlers/reset_password.ts
|
|
52
|
+
var resetPasswordHandler = async (request, {
|
|
53
|
+
passwordRecoveryService
|
|
54
|
+
}) => {
|
|
55
|
+
const { token, password, passwordConfirm } = await request.json();
|
|
56
|
+
await passwordRecoveryService.resetPassword(token, password, passwordConfirm);
|
|
57
|
+
return NO_CONTENT();
|
|
58
|
+
};
|
|
59
|
+
export {
|
|
60
|
+
resetPasswordHandler
|
|
61
|
+
};
|
|
@@ -102,12 +102,9 @@ var signupHandler = async (request, {
|
|
|
102
102
|
if (!passwordConfirm) {
|
|
103
103
|
return BAD_REQUEST("\uBE44\uBC00\uBC88\uD638 \uD655\uC778\uC744 \uC785\uB825\uD574\uC8FC\uC138\uC694.");
|
|
104
104
|
}
|
|
105
|
-
if (!name) {
|
|
106
|
-
return BAD_REQUEST("\uC774\uB984\uC744 \uC785\uB825\uD574\uC8FC\uC138\uC694.");
|
|
107
|
-
}
|
|
108
105
|
const existing = await authService.authRepository.findCredentialById(email);
|
|
109
106
|
if (existing) {
|
|
110
|
-
return CONFLICT("\uC774\
|
|
107
|
+
return CONFLICT("\uC774\uBBF8 \uAC00\uC785\uD55C \uC774\uBA54\uC77C\uC785\uB2C8\uB2E4.");
|
|
111
108
|
}
|
|
112
109
|
if (password !== passwordConfirm) {
|
|
113
110
|
return BAD_REQUEST("\uBE44\uBC00\uBC88\uD638\uAC00 \uC77C\uCE58\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.");
|
|
@@ -127,7 +124,22 @@ var signupHandler = async (request, {
|
|
|
127
124
|
password: bcrypt.hashSync(password, 10)
|
|
128
125
|
});
|
|
129
126
|
const { accessToken, refreshToken } = await authService.issueTokenPair(user);
|
|
130
|
-
|
|
127
|
+
const searchParams = new URL(request.url).searchParams;
|
|
128
|
+
const type = searchParams.get("type");
|
|
129
|
+
if (type === "json") {
|
|
130
|
+
return CREATED({ accessToken, refreshToken });
|
|
131
|
+
}
|
|
132
|
+
const [accessTokenSetCookie, refreshTokenSetCookie] = await Promise.all([
|
|
133
|
+
authService.getAccessTokenSetCookie(accessToken),
|
|
134
|
+
authService.getRefreshTokenSetCookie(refreshToken)
|
|
135
|
+
]);
|
|
136
|
+
const payload = authService.jwtManager.decode(accessToken);
|
|
137
|
+
const headers = new Headers();
|
|
138
|
+
headers.append("Set-Cookie", accessTokenSetCookie);
|
|
139
|
+
headers.append("Set-Cookie", refreshTokenSetCookie);
|
|
140
|
+
return CREATED(payload, {
|
|
141
|
+
headers
|
|
142
|
+
});
|
|
131
143
|
};
|
|
132
144
|
// Annotate the CommonJS export names for ESM import in node:
|
|
133
145
|
0 && (module.exports = {
|
|
@@ -68,12 +68,9 @@ var signupHandler = async (request, {
|
|
|
68
68
|
if (!passwordConfirm) {
|
|
69
69
|
return BAD_REQUEST("\uBE44\uBC00\uBC88\uD638 \uD655\uC778\uC744 \uC785\uB825\uD574\uC8FC\uC138\uC694.");
|
|
70
70
|
}
|
|
71
|
-
if (!name) {
|
|
72
|
-
return BAD_REQUEST("\uC774\uB984\uC744 \uC785\uB825\uD574\uC8FC\uC138\uC694.");
|
|
73
|
-
}
|
|
74
71
|
const existing = await authService.authRepository.findCredentialById(email);
|
|
75
72
|
if (existing) {
|
|
76
|
-
return CONFLICT("\uC774\
|
|
73
|
+
return CONFLICT("\uC774\uBBF8 \uAC00\uC785\uD55C \uC774\uBA54\uC77C\uC785\uB2C8\uB2E4.");
|
|
77
74
|
}
|
|
78
75
|
if (password !== passwordConfirm) {
|
|
79
76
|
return BAD_REQUEST("\uBE44\uBC00\uBC88\uD638\uAC00 \uC77C\uCE58\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.");
|
|
@@ -93,7 +90,22 @@ var signupHandler = async (request, {
|
|
|
93
90
|
password: bcrypt.hashSync(password, 10)
|
|
94
91
|
});
|
|
95
92
|
const { accessToken, refreshToken } = await authService.issueTokenPair(user);
|
|
96
|
-
|
|
93
|
+
const searchParams = new URL(request.url).searchParams;
|
|
94
|
+
const type = searchParams.get("type");
|
|
95
|
+
if (type === "json") {
|
|
96
|
+
return CREATED({ accessToken, refreshToken });
|
|
97
|
+
}
|
|
98
|
+
const [accessTokenSetCookie, refreshTokenSetCookie] = await Promise.all([
|
|
99
|
+
authService.getAccessTokenSetCookie(accessToken),
|
|
100
|
+
authService.getRefreshTokenSetCookie(refreshToken)
|
|
101
|
+
]);
|
|
102
|
+
const payload = authService.jwtManager.decode(accessToken);
|
|
103
|
+
const headers = new Headers();
|
|
104
|
+
headers.append("Set-Cookie", accessTokenSetCookie);
|
|
105
|
+
headers.append("Set-Cookie", refreshTokenSetCookie);
|
|
106
|
+
return CREATED(payload, {
|
|
107
|
+
headers
|
|
108
|
+
});
|
|
97
109
|
};
|
|
98
110
|
export {
|
|
99
111
|
signupHandler
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { AuthRepository } from './auth_repository.mjs';
|
|
2
|
+
import { JWTManager } from './jwt_manager.mjs';
|
|
3
|
+
import 'jose';
|
|
4
|
+
|
|
5
|
+
declare class PasswordRecoveryService {
|
|
6
|
+
siteOrigin: string;
|
|
7
|
+
siteName: string;
|
|
8
|
+
jwtManager: JWTManager;
|
|
9
|
+
authRepository: AuthRepository;
|
|
10
|
+
emailCredentials: {
|
|
11
|
+
service: string;
|
|
12
|
+
user: string;
|
|
13
|
+
pass: string;
|
|
14
|
+
};
|
|
15
|
+
resetPasswordTokenSecret: string;
|
|
16
|
+
resetPasswordTokenExpiresIn: string;
|
|
17
|
+
constructor({ siteOrigin, siteName, jwtManager, authRepository, emailCredentials, resetPasswordTokenSecret, resetPasswordTokenExpiresIn, }: {
|
|
18
|
+
siteOrigin: string;
|
|
19
|
+
siteName: string;
|
|
20
|
+
jwtManager: JWTManager;
|
|
21
|
+
authRepository: AuthRepository;
|
|
22
|
+
emailCredentials: {
|
|
23
|
+
service: string;
|
|
24
|
+
user: string;
|
|
25
|
+
pass: string;
|
|
26
|
+
};
|
|
27
|
+
resetPasswordTokenSecret: string;
|
|
28
|
+
resetPasswordTokenExpiresIn?: string;
|
|
29
|
+
});
|
|
30
|
+
requestPasswordReset(email: string): Promise<void>;
|
|
31
|
+
resetPassword(token: string, password: string, passwordConfirm: string): Promise<void>;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export { PasswordRecoveryService };
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { AuthRepository } from './auth_repository.js';
|
|
2
|
+
import { JWTManager } from './jwt_manager.js';
|
|
3
|
+
import 'jose';
|
|
4
|
+
|
|
5
|
+
declare class PasswordRecoveryService {
|
|
6
|
+
siteOrigin: string;
|
|
7
|
+
siteName: string;
|
|
8
|
+
jwtManager: JWTManager;
|
|
9
|
+
authRepository: AuthRepository;
|
|
10
|
+
emailCredentials: {
|
|
11
|
+
service: string;
|
|
12
|
+
user: string;
|
|
13
|
+
pass: string;
|
|
14
|
+
};
|
|
15
|
+
resetPasswordTokenSecret: string;
|
|
16
|
+
resetPasswordTokenExpiresIn: string;
|
|
17
|
+
constructor({ siteOrigin, siteName, jwtManager, authRepository, emailCredentials, resetPasswordTokenSecret, resetPasswordTokenExpiresIn, }: {
|
|
18
|
+
siteOrigin: string;
|
|
19
|
+
siteName: string;
|
|
20
|
+
jwtManager: JWTManager;
|
|
21
|
+
authRepository: AuthRepository;
|
|
22
|
+
emailCredentials: {
|
|
23
|
+
service: string;
|
|
24
|
+
user: string;
|
|
25
|
+
pass: string;
|
|
26
|
+
};
|
|
27
|
+
resetPasswordTokenSecret: string;
|
|
28
|
+
resetPasswordTokenExpiresIn?: string;
|
|
29
|
+
});
|
|
30
|
+
requestPasswordReset(email: string): Promise<void>;
|
|
31
|
+
resetPassword(token: string, password: string, passwordConfirm: string): Promise<void>;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export { PasswordRecoveryService };
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// src/auth/password_recovery.ts
|
|
31
|
+
var password_recovery_exports = {};
|
|
32
|
+
__export(password_recovery_exports, {
|
|
33
|
+
PasswordRecoveryService: () => PasswordRecoveryService
|
|
34
|
+
});
|
|
35
|
+
module.exports = __toCommonJS(password_recovery_exports);
|
|
36
|
+
var import_nodemailer = __toESM(require("nodemailer"));
|
|
37
|
+
|
|
38
|
+
// src/http/response.ts
|
|
39
|
+
var createJsonResponse = (status) => {
|
|
40
|
+
return (data = {}, init) => {
|
|
41
|
+
return Response.json(data, { status, ...init });
|
|
42
|
+
};
|
|
43
|
+
};
|
|
44
|
+
var OK = createJsonResponse(200);
|
|
45
|
+
var CREATED = createJsonResponse(201);
|
|
46
|
+
var ACCEPTED = createJsonResponse(202);
|
|
47
|
+
var createException = (status, defaultMessage = "\uC624\uB958\uAC00 \uBC1C\uC0DD\uD588\uC2B5\uB2C8\uB2E4.") => {
|
|
48
|
+
return (message = defaultMessage, init) => {
|
|
49
|
+
return createJsonResponse(status)({ message }, init);
|
|
50
|
+
};
|
|
51
|
+
};
|
|
52
|
+
var BAD_REQUEST = createException(400, "\uC694\uCCAD\uC774 \uC62C\uBC14\uB974\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.");
|
|
53
|
+
var UNAUTHORIZED = createException(401, "\uC778\uC99D\uC774 \uD544\uC694\uD569\uB2C8\uB2E4.");
|
|
54
|
+
var FORBIDDEN = createException(403, "\uAD8C\uD55C\uC774 \uC5C6\uC2B5\uB2C8\uB2E4.");
|
|
55
|
+
var NOT_FOUND = createException(
|
|
56
|
+
404,
|
|
57
|
+
"\uC694\uCCAD\uD55C \uB9AC\uC18C\uC2A4\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4."
|
|
58
|
+
);
|
|
59
|
+
var METHOD_NOT_ALLOWED = createException(
|
|
60
|
+
405,
|
|
61
|
+
"\uBA54\uC11C\uB4DC\uB97C \uC0AC\uC6A9\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4."
|
|
62
|
+
);
|
|
63
|
+
var NOT_ACCEPTABLE = createException(
|
|
64
|
+
406,
|
|
65
|
+
"\uC694\uCCAD\uD55C \uD615\uC2DD\uC744 \uC0AC\uC6A9\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4."
|
|
66
|
+
);
|
|
67
|
+
var REQUEST_TIMEOUT = createException(
|
|
68
|
+
408,
|
|
69
|
+
"\uC694\uCCAD \uC2DC\uAC04\uC774 \uCD08\uACFC\uB418\uC5C8\uC2B5\uB2C8\uB2E4."
|
|
70
|
+
);
|
|
71
|
+
var CONFLICT = createException(409, "\uC694\uCCAD\uC774 \uCDA9\uB3CC\uD588\uC2B5\uB2C8\uB2E4.");
|
|
72
|
+
var UNPROCESSABLE_ENTITY = createException(
|
|
73
|
+
422,
|
|
74
|
+
"\uCC98\uB9AC\uD560 \uC218 \uC5C6\uB294 \uC5D4\uD2F0\uD2F0\uC785\uB2C8\uB2E4."
|
|
75
|
+
);
|
|
76
|
+
var TOO_MANY_REQUESTS = createException(429, "\uC694\uCCAD\uC774 \uB108\uBB34 \uB9CE\uC2B5\uB2C8\uB2E4.");
|
|
77
|
+
var INTERNAL_SERVER_ERROR = createException(
|
|
78
|
+
500,
|
|
79
|
+
"\uC608\uAE30\uCE58 \uBABB\uD55C \uC624\uB958\uAC00 \uBC1C\uC0DD\uD588\uC2B5\uB2C8\uB2E4."
|
|
80
|
+
);
|
|
81
|
+
|
|
82
|
+
// src/auth/password_recovery.ts
|
|
83
|
+
var import_bcryptjs = __toESM(require("bcryptjs"));
|
|
84
|
+
var PasswordRecoveryService = class {
|
|
85
|
+
siteOrigin;
|
|
86
|
+
siteName;
|
|
87
|
+
jwtManager;
|
|
88
|
+
authRepository;
|
|
89
|
+
emailCredentials;
|
|
90
|
+
resetPasswordTokenSecret;
|
|
91
|
+
resetPasswordTokenExpiresIn;
|
|
92
|
+
constructor({
|
|
93
|
+
siteOrigin,
|
|
94
|
+
siteName,
|
|
95
|
+
jwtManager,
|
|
96
|
+
authRepository,
|
|
97
|
+
emailCredentials,
|
|
98
|
+
resetPasswordTokenSecret,
|
|
99
|
+
resetPasswordTokenExpiresIn = "1h"
|
|
100
|
+
}) {
|
|
101
|
+
this.siteOrigin = siteOrigin;
|
|
102
|
+
this.siteName = siteName;
|
|
103
|
+
this.jwtManager = jwtManager;
|
|
104
|
+
this.authRepository = authRepository;
|
|
105
|
+
this.emailCredentials = emailCredentials;
|
|
106
|
+
this.resetPasswordTokenSecret = resetPasswordTokenSecret;
|
|
107
|
+
this.resetPasswordTokenExpiresIn = resetPasswordTokenExpiresIn;
|
|
108
|
+
}
|
|
109
|
+
async requestPasswordReset(email) {
|
|
110
|
+
const credential = await this.authRepository.findCredentialById(email);
|
|
111
|
+
if (!credential) {
|
|
112
|
+
throw NOT_FOUND("\uAC00\uC785\uB418\uC9C0 \uC54A\uC740 \uC774\uBA54\uC77C\uC785\uB2C8\uB2E4.");
|
|
113
|
+
}
|
|
114
|
+
const transporter = import_nodemailer.default.createTransport({
|
|
115
|
+
service: this.emailCredentials.service,
|
|
116
|
+
auth: {
|
|
117
|
+
user: this.emailCredentials.user,
|
|
118
|
+
pass: this.emailCredentials.pass
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
const token = await this.jwtManager.sign(
|
|
122
|
+
{
|
|
123
|
+
id: credential.id
|
|
124
|
+
},
|
|
125
|
+
this.resetPasswordTokenSecret,
|
|
126
|
+
{
|
|
127
|
+
expiresIn: this.resetPasswordTokenExpiresIn
|
|
128
|
+
}
|
|
129
|
+
);
|
|
130
|
+
const link = `${this.siteOrigin}/reset-password?token=${token}`;
|
|
131
|
+
const mailOptions = {
|
|
132
|
+
from: process.env.EMAIL_USER,
|
|
133
|
+
to: email,
|
|
134
|
+
subject: `${this.siteName} \uBE44\uBC00\uBC88\uD638 \uC7AC\uC124\uC815`,
|
|
135
|
+
html: `<main>
|
|
136
|
+
<p>\uBE44\uBC00\uBC88\uD638 \uC7AC\uC124\uC815\uC744 \uC704\uD574 \uC544\uB798 \uB9C1\uD06C\uB97C \uD074\uB9AD\uD574 \uC8FC\uC138\uC694. \uB9C1\uD06C\uB294 \uD55C \uC2DC\uAC04 \uB3D9\uC548 \uC720\uD6A8\uD569\uB2C8\uB2E4. \uB2E4\uB978 \uC0AC\uB78C\uC5D0\uAC8C \uACF5\uC720\uD558\uC9C0 \uB9C8\uC138\uC694.</p>
|
|
137
|
+
<a href="${link}" target="_blank">${link}</a>
|
|
138
|
+
</main>`
|
|
139
|
+
};
|
|
140
|
+
await transporter.sendMail(mailOptions);
|
|
141
|
+
}
|
|
142
|
+
async resetPassword(token, password, passwordConfirm) {
|
|
143
|
+
const payload = await this.jwtManager.verify(
|
|
144
|
+
token,
|
|
145
|
+
this.resetPasswordTokenSecret
|
|
146
|
+
);
|
|
147
|
+
if (!payload) {
|
|
148
|
+
throw UNAUTHORIZED("\uC720\uD6A8\uD558\uC9C0 \uC54A\uC740 \uD1A0\uD070\uC785\uB2C8\uB2E4.");
|
|
149
|
+
}
|
|
150
|
+
if (typeof payload.id !== "string") {
|
|
151
|
+
throw UNAUTHORIZED("\uD1A0\uD070\uC774 \uC704\uC870\uB418\uC5C8\uC2B5\uB2C8\uB2E4.");
|
|
152
|
+
}
|
|
153
|
+
const credential = await this.authRepository.findCredentialById(payload.id);
|
|
154
|
+
if (!credential) {
|
|
155
|
+
throw NOT_FOUND("\uC874\uC7AC\uD558\uC9C0 \uC54A\uB294 \uACC4\uC815\uC785\uB2C8\uB2E4.");
|
|
156
|
+
}
|
|
157
|
+
if (typeof password !== "string" || !password.trim()) {
|
|
158
|
+
throw BAD_REQUEST("\uC720\uD6A8\uD558\uC9C0 \uC54A\uC740 \uBE44\uBC00\uBC88\uD638\uC785\uB2C8\uB2E4.");
|
|
159
|
+
}
|
|
160
|
+
if (password !== passwordConfirm) {
|
|
161
|
+
throw BAD_REQUEST("\uBE44\uBC00\uBC88\uD638\uAC00 \uC77C\uCE58\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.");
|
|
162
|
+
}
|
|
163
|
+
await this.authRepository.updatePassword(credential.id, import_bcryptjs.default.hashSync(password, 10));
|
|
164
|
+
}
|
|
165
|
+
};
|
|
166
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
167
|
+
0 && (module.exports = {
|
|
168
|
+
PasswordRecoveryService
|
|
169
|
+
});
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
// src/auth/password_recovery.ts
|
|
2
|
+
import nodemailer from "nodemailer";
|
|
3
|
+
|
|
4
|
+
// src/http/response.ts
|
|
5
|
+
var createJsonResponse = (status) => {
|
|
6
|
+
return (data = {}, init) => {
|
|
7
|
+
return Response.json(data, { status, ...init });
|
|
8
|
+
};
|
|
9
|
+
};
|
|
10
|
+
var OK = createJsonResponse(200);
|
|
11
|
+
var CREATED = createJsonResponse(201);
|
|
12
|
+
var ACCEPTED = createJsonResponse(202);
|
|
13
|
+
var createException = (status, defaultMessage = "\uC624\uB958\uAC00 \uBC1C\uC0DD\uD588\uC2B5\uB2C8\uB2E4.") => {
|
|
14
|
+
return (message = defaultMessage, init) => {
|
|
15
|
+
return createJsonResponse(status)({ message }, init);
|
|
16
|
+
};
|
|
17
|
+
};
|
|
18
|
+
var BAD_REQUEST = createException(400, "\uC694\uCCAD\uC774 \uC62C\uBC14\uB974\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.");
|
|
19
|
+
var UNAUTHORIZED = createException(401, "\uC778\uC99D\uC774 \uD544\uC694\uD569\uB2C8\uB2E4.");
|
|
20
|
+
var FORBIDDEN = createException(403, "\uAD8C\uD55C\uC774 \uC5C6\uC2B5\uB2C8\uB2E4.");
|
|
21
|
+
var NOT_FOUND = createException(
|
|
22
|
+
404,
|
|
23
|
+
"\uC694\uCCAD\uD55C \uB9AC\uC18C\uC2A4\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4."
|
|
24
|
+
);
|
|
25
|
+
var METHOD_NOT_ALLOWED = createException(
|
|
26
|
+
405,
|
|
27
|
+
"\uBA54\uC11C\uB4DC\uB97C \uC0AC\uC6A9\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4."
|
|
28
|
+
);
|
|
29
|
+
var NOT_ACCEPTABLE = createException(
|
|
30
|
+
406,
|
|
31
|
+
"\uC694\uCCAD\uD55C \uD615\uC2DD\uC744 \uC0AC\uC6A9\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4."
|
|
32
|
+
);
|
|
33
|
+
var REQUEST_TIMEOUT = createException(
|
|
34
|
+
408,
|
|
35
|
+
"\uC694\uCCAD \uC2DC\uAC04\uC774 \uCD08\uACFC\uB418\uC5C8\uC2B5\uB2C8\uB2E4."
|
|
36
|
+
);
|
|
37
|
+
var CONFLICT = createException(409, "\uC694\uCCAD\uC774 \uCDA9\uB3CC\uD588\uC2B5\uB2C8\uB2E4.");
|
|
38
|
+
var UNPROCESSABLE_ENTITY = createException(
|
|
39
|
+
422,
|
|
40
|
+
"\uCC98\uB9AC\uD560 \uC218 \uC5C6\uB294 \uC5D4\uD2F0\uD2F0\uC785\uB2C8\uB2E4."
|
|
41
|
+
);
|
|
42
|
+
var TOO_MANY_REQUESTS = createException(429, "\uC694\uCCAD\uC774 \uB108\uBB34 \uB9CE\uC2B5\uB2C8\uB2E4.");
|
|
43
|
+
var INTERNAL_SERVER_ERROR = createException(
|
|
44
|
+
500,
|
|
45
|
+
"\uC608\uAE30\uCE58 \uBABB\uD55C \uC624\uB958\uAC00 \uBC1C\uC0DD\uD588\uC2B5\uB2C8\uB2E4."
|
|
46
|
+
);
|
|
47
|
+
|
|
48
|
+
// src/auth/password_recovery.ts
|
|
49
|
+
import bcrypt from "bcryptjs";
|
|
50
|
+
var PasswordRecoveryService = class {
|
|
51
|
+
siteOrigin;
|
|
52
|
+
siteName;
|
|
53
|
+
jwtManager;
|
|
54
|
+
authRepository;
|
|
55
|
+
emailCredentials;
|
|
56
|
+
resetPasswordTokenSecret;
|
|
57
|
+
resetPasswordTokenExpiresIn;
|
|
58
|
+
constructor({
|
|
59
|
+
siteOrigin,
|
|
60
|
+
siteName,
|
|
61
|
+
jwtManager,
|
|
62
|
+
authRepository,
|
|
63
|
+
emailCredentials,
|
|
64
|
+
resetPasswordTokenSecret,
|
|
65
|
+
resetPasswordTokenExpiresIn = "1h"
|
|
66
|
+
}) {
|
|
67
|
+
this.siteOrigin = siteOrigin;
|
|
68
|
+
this.siteName = siteName;
|
|
69
|
+
this.jwtManager = jwtManager;
|
|
70
|
+
this.authRepository = authRepository;
|
|
71
|
+
this.emailCredentials = emailCredentials;
|
|
72
|
+
this.resetPasswordTokenSecret = resetPasswordTokenSecret;
|
|
73
|
+
this.resetPasswordTokenExpiresIn = resetPasswordTokenExpiresIn;
|
|
74
|
+
}
|
|
75
|
+
async requestPasswordReset(email) {
|
|
76
|
+
const credential = await this.authRepository.findCredentialById(email);
|
|
77
|
+
if (!credential) {
|
|
78
|
+
throw NOT_FOUND("\uAC00\uC785\uB418\uC9C0 \uC54A\uC740 \uC774\uBA54\uC77C\uC785\uB2C8\uB2E4.");
|
|
79
|
+
}
|
|
80
|
+
const transporter = nodemailer.createTransport({
|
|
81
|
+
service: this.emailCredentials.service,
|
|
82
|
+
auth: {
|
|
83
|
+
user: this.emailCredentials.user,
|
|
84
|
+
pass: this.emailCredentials.pass
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
const token = await this.jwtManager.sign(
|
|
88
|
+
{
|
|
89
|
+
id: credential.id
|
|
90
|
+
},
|
|
91
|
+
this.resetPasswordTokenSecret,
|
|
92
|
+
{
|
|
93
|
+
expiresIn: this.resetPasswordTokenExpiresIn
|
|
94
|
+
}
|
|
95
|
+
);
|
|
96
|
+
const link = `${this.siteOrigin}/reset-password?token=${token}`;
|
|
97
|
+
const mailOptions = {
|
|
98
|
+
from: process.env.EMAIL_USER,
|
|
99
|
+
to: email,
|
|
100
|
+
subject: `${this.siteName} \uBE44\uBC00\uBC88\uD638 \uC7AC\uC124\uC815`,
|
|
101
|
+
html: `<main>
|
|
102
|
+
<p>\uBE44\uBC00\uBC88\uD638 \uC7AC\uC124\uC815\uC744 \uC704\uD574 \uC544\uB798 \uB9C1\uD06C\uB97C \uD074\uB9AD\uD574 \uC8FC\uC138\uC694. \uB9C1\uD06C\uB294 \uD55C \uC2DC\uAC04 \uB3D9\uC548 \uC720\uD6A8\uD569\uB2C8\uB2E4. \uB2E4\uB978 \uC0AC\uB78C\uC5D0\uAC8C \uACF5\uC720\uD558\uC9C0 \uB9C8\uC138\uC694.</p>
|
|
103
|
+
<a href="${link}" target="_blank">${link}</a>
|
|
104
|
+
</main>`
|
|
105
|
+
};
|
|
106
|
+
await transporter.sendMail(mailOptions);
|
|
107
|
+
}
|
|
108
|
+
async resetPassword(token, password, passwordConfirm) {
|
|
109
|
+
const payload = await this.jwtManager.verify(
|
|
110
|
+
token,
|
|
111
|
+
this.resetPasswordTokenSecret
|
|
112
|
+
);
|
|
113
|
+
if (!payload) {
|
|
114
|
+
throw UNAUTHORIZED("\uC720\uD6A8\uD558\uC9C0 \uC54A\uC740 \uD1A0\uD070\uC785\uB2C8\uB2E4.");
|
|
115
|
+
}
|
|
116
|
+
if (typeof payload.id !== "string") {
|
|
117
|
+
throw UNAUTHORIZED("\uD1A0\uD070\uC774 \uC704\uC870\uB418\uC5C8\uC2B5\uB2C8\uB2E4.");
|
|
118
|
+
}
|
|
119
|
+
const credential = await this.authRepository.findCredentialById(payload.id);
|
|
120
|
+
if (!credential) {
|
|
121
|
+
throw NOT_FOUND("\uC874\uC7AC\uD558\uC9C0 \uC54A\uB294 \uACC4\uC815\uC785\uB2C8\uB2E4.");
|
|
122
|
+
}
|
|
123
|
+
if (typeof password !== "string" || !password.trim()) {
|
|
124
|
+
throw BAD_REQUEST("\uC720\uD6A8\uD558\uC9C0 \uC54A\uC740 \uBE44\uBC00\uBC88\uD638\uC785\uB2C8\uB2E4.");
|
|
125
|
+
}
|
|
126
|
+
if (password !== passwordConfirm) {
|
|
127
|
+
throw BAD_REQUEST("\uBE44\uBC00\uBC88\uD638\uAC00 \uC77C\uCE58\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.");
|
|
128
|
+
}
|
|
129
|
+
await this.authRepository.updatePassword(credential.id, bcrypt.hashSync(password, 10));
|
|
130
|
+
}
|
|
131
|
+
};
|
|
132
|
+
export {
|
|
133
|
+
PasswordRecoveryService
|
|
134
|
+
};
|
package/dist/route/api.d.mts
CHANGED
|
@@ -2,6 +2,7 @@ import { AuthService } from '../auth/auth_service.mjs';
|
|
|
2
2
|
import { FileService } from '../file/file_service.mjs';
|
|
3
3
|
import { ThirdpartyAuth } from '../auth/thirdparty_auth.mjs';
|
|
4
4
|
import { LoaderFunctionArgs, ActionFunctionArgs } from 'react-router';
|
|
5
|
+
import { PasswordRecoveryService } from '../auth/password_recovery.mjs';
|
|
5
6
|
import 'jose';
|
|
6
7
|
import '../auth/jwt_manager.mjs';
|
|
7
8
|
import '../file/object_storage.mjs';
|
|
@@ -9,9 +10,10 @@ import '@aws-sdk/client-s3';
|
|
|
9
10
|
import '../auth/auth_repository.mjs';
|
|
10
11
|
import '../file/file_repository.mjs';
|
|
11
12
|
|
|
12
|
-
declare const createAPIHandler: <TFile>({ authService, fileService, getThirdPartyAuth, signupTokenSecret, }: {
|
|
13
|
+
declare const createAPIHandler: <TFile>({ authService, fileService, passwordRecoveryService, getThirdPartyAuth, signupTokenSecret, }: {
|
|
13
14
|
authService: AuthService<TFile>;
|
|
14
15
|
fileService: FileService<TFile>;
|
|
16
|
+
passwordRecoveryService: PasswordRecoveryService;
|
|
15
17
|
getThirdPartyAuth: (provider: string) => ThirdpartyAuth;
|
|
16
18
|
signupTokenSecret: string;
|
|
17
19
|
}) => ({ request, params }: LoaderFunctionArgs | ActionFunctionArgs) => Promise<Response>;
|
package/dist/route/api.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { AuthService } from '../auth/auth_service.js';
|
|
|
2
2
|
import { FileService } from '../file/file_service.js';
|
|
3
3
|
import { ThirdpartyAuth } from '../auth/thirdparty_auth.js';
|
|
4
4
|
import { LoaderFunctionArgs, ActionFunctionArgs } from 'react-router';
|
|
5
|
+
import { PasswordRecoveryService } from '../auth/password_recovery.js';
|
|
5
6
|
import 'jose';
|
|
6
7
|
import '../auth/jwt_manager.js';
|
|
7
8
|
import '../file/object_storage.js';
|
|
@@ -9,9 +10,10 @@ import '@aws-sdk/client-s3';
|
|
|
9
10
|
import '../auth/auth_repository.js';
|
|
10
11
|
import '../file/file_repository.js';
|
|
11
12
|
|
|
12
|
-
declare const createAPIHandler: <TFile>({ authService, fileService, getThirdPartyAuth, signupTokenSecret, }: {
|
|
13
|
+
declare const createAPIHandler: <TFile>({ authService, fileService, passwordRecoveryService, getThirdPartyAuth, signupTokenSecret, }: {
|
|
13
14
|
authService: AuthService<TFile>;
|
|
14
15
|
fileService: FileService<TFile>;
|
|
16
|
+
passwordRecoveryService: PasswordRecoveryService;
|
|
15
17
|
getThirdPartyAuth: (provider: string) => ThirdpartyAuth;
|
|
16
18
|
signupTokenSecret: string;
|
|
17
19
|
}) => ({ request, params }: LoaderFunctionArgs | ActionFunctionArgs) => Promise<Response>;
|
package/dist/route/api.js
CHANGED
|
@@ -233,7 +233,7 @@ var loginHandler = async (request, {
|
|
|
233
233
|
}) => {
|
|
234
234
|
const { id, password } = await request.json();
|
|
235
235
|
try {
|
|
236
|
-
const { accessToken, refreshToken } = await authService.
|
|
236
|
+
const { accessToken, refreshToken } = await authService.login({
|
|
237
237
|
id,
|
|
238
238
|
password
|
|
239
239
|
});
|
|
@@ -327,12 +327,9 @@ var signupHandler = async (request, {
|
|
|
327
327
|
if (!passwordConfirm) {
|
|
328
328
|
return BAD_REQUEST("\uBE44\uBC00\uBC88\uD638 \uD655\uC778\uC744 \uC785\uB825\uD574\uC8FC\uC138\uC694.");
|
|
329
329
|
}
|
|
330
|
-
if (!name) {
|
|
331
|
-
return BAD_REQUEST("\uC774\uB984\uC744 \uC785\uB825\uD574\uC8FC\uC138\uC694.");
|
|
332
|
-
}
|
|
333
330
|
const existing = await authService.authRepository.findCredentialById(email);
|
|
334
331
|
if (existing) {
|
|
335
|
-
return CONFLICT("\uC774\
|
|
332
|
+
return CONFLICT("\uC774\uBBF8 \uAC00\uC785\uD55C \uC774\uBA54\uC77C\uC785\uB2C8\uB2E4.");
|
|
336
333
|
}
|
|
337
334
|
if (password !== passwordConfirm) {
|
|
338
335
|
return BAD_REQUEST("\uBE44\uBC00\uBC88\uD638\uAC00 \uC77C\uCE58\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.");
|
|
@@ -352,7 +349,22 @@ var signupHandler = async (request, {
|
|
|
352
349
|
password: bcrypt.hashSync(password, 10)
|
|
353
350
|
});
|
|
354
351
|
const { accessToken, refreshToken } = await authService.issueTokenPair(user);
|
|
355
|
-
|
|
352
|
+
const searchParams = new URL(request.url).searchParams;
|
|
353
|
+
const type = searchParams.get("type");
|
|
354
|
+
if (type === "json") {
|
|
355
|
+
return CREATED({ accessToken, refreshToken });
|
|
356
|
+
}
|
|
357
|
+
const [accessTokenSetCookie, refreshTokenSetCookie] = await Promise.all([
|
|
358
|
+
authService.getAccessTokenSetCookie(accessToken),
|
|
359
|
+
authService.getRefreshTokenSetCookie(refreshToken)
|
|
360
|
+
]);
|
|
361
|
+
const payload = authService.jwtManager.decode(accessToken);
|
|
362
|
+
const headers = new Headers();
|
|
363
|
+
headers.append("Set-Cookie", accessTokenSetCookie);
|
|
364
|
+
headers.append("Set-Cookie", refreshTokenSetCookie);
|
|
365
|
+
return CREATED(payload, {
|
|
366
|
+
headers
|
|
367
|
+
});
|
|
356
368
|
};
|
|
357
369
|
|
|
358
370
|
// src/auth/handlers/signup_with_thirdparty.ts
|
|
@@ -405,10 +417,34 @@ var signUpWithThirdpartyHandler = async (request, {
|
|
|
405
417
|
return CREATED({ accessToken, refreshToken });
|
|
406
418
|
};
|
|
407
419
|
|
|
420
|
+
// src/auth/handlers/request_password_reset.ts
|
|
421
|
+
var requestPasswordResetHandler = async (request, {
|
|
422
|
+
passwordRecoveryService
|
|
423
|
+
}) => {
|
|
424
|
+
const { email } = await request.json();
|
|
425
|
+
try {
|
|
426
|
+
await passwordRecoveryService.requestPasswordReset(email);
|
|
427
|
+
return CREATED({ message: "\uBE44\uBC00\uBC88\uD638 \uC7AC\uC124\uC815 \uC774\uBA54\uC77C\uC744 \uC804\uC1A1\uD588\uC2B5\uB2C8\uB2E4." });
|
|
428
|
+
} catch (error) {
|
|
429
|
+
console.error(error);
|
|
430
|
+
return INTERNAL_SERVER_ERROR("\uC774\uBA54\uC77C \uC804\uC1A1\uC5D0 \uC2E4\uD328\uD588\uC2B5\uB2C8\uB2E4.");
|
|
431
|
+
}
|
|
432
|
+
};
|
|
433
|
+
|
|
434
|
+
// src/auth/handlers/reset_password.ts
|
|
435
|
+
var resetPasswordHandler = async (request, {
|
|
436
|
+
passwordRecoveryService
|
|
437
|
+
}) => {
|
|
438
|
+
const { token, password, passwordConfirm } = await request.json();
|
|
439
|
+
await passwordRecoveryService.resetPassword(token, password, passwordConfirm);
|
|
440
|
+
return NO_CONTENT();
|
|
441
|
+
};
|
|
442
|
+
|
|
408
443
|
// src/route/api.ts
|
|
409
444
|
var createAPIHandler = ({
|
|
410
445
|
authService,
|
|
411
446
|
fileService,
|
|
447
|
+
passwordRecoveryService,
|
|
412
448
|
getThirdPartyAuth,
|
|
413
449
|
signupTokenSecret
|
|
414
450
|
}) => {
|
|
@@ -504,6 +540,12 @@ var createAPIHandler = ({
|
|
|
504
540
|
}
|
|
505
541
|
}
|
|
506
542
|
}
|
|
543
|
+
case "request-password-reset": {
|
|
544
|
+
return requestPasswordResetHandler(request, { passwordRecoveryService });
|
|
545
|
+
}
|
|
546
|
+
case "reset-password": {
|
|
547
|
+
return resetPasswordHandler(request, { passwordRecoveryService });
|
|
548
|
+
}
|
|
507
549
|
}
|
|
508
550
|
}
|
|
509
551
|
case "files": {
|
package/dist/route/api.mjs
CHANGED
|
@@ -197,7 +197,7 @@ var loginHandler = async (request, {
|
|
|
197
197
|
}) => {
|
|
198
198
|
const { id, password } = await request.json();
|
|
199
199
|
try {
|
|
200
|
-
const { accessToken, refreshToken } = await authService.
|
|
200
|
+
const { accessToken, refreshToken } = await authService.login({
|
|
201
201
|
id,
|
|
202
202
|
password
|
|
203
203
|
});
|
|
@@ -291,12 +291,9 @@ var signupHandler = async (request, {
|
|
|
291
291
|
if (!passwordConfirm) {
|
|
292
292
|
return BAD_REQUEST("\uBE44\uBC00\uBC88\uD638 \uD655\uC778\uC744 \uC785\uB825\uD574\uC8FC\uC138\uC694.");
|
|
293
293
|
}
|
|
294
|
-
if (!name) {
|
|
295
|
-
return BAD_REQUEST("\uC774\uB984\uC744 \uC785\uB825\uD574\uC8FC\uC138\uC694.");
|
|
296
|
-
}
|
|
297
294
|
const existing = await authService.authRepository.findCredentialById(email);
|
|
298
295
|
if (existing) {
|
|
299
|
-
return CONFLICT("\uC774\
|
|
296
|
+
return CONFLICT("\uC774\uBBF8 \uAC00\uC785\uD55C \uC774\uBA54\uC77C\uC785\uB2C8\uB2E4.");
|
|
300
297
|
}
|
|
301
298
|
if (password !== passwordConfirm) {
|
|
302
299
|
return BAD_REQUEST("\uBE44\uBC00\uBC88\uD638\uAC00 \uC77C\uCE58\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.");
|
|
@@ -316,7 +313,22 @@ var signupHandler = async (request, {
|
|
|
316
313
|
password: bcrypt.hashSync(password, 10)
|
|
317
314
|
});
|
|
318
315
|
const { accessToken, refreshToken } = await authService.issueTokenPair(user);
|
|
319
|
-
|
|
316
|
+
const searchParams = new URL(request.url).searchParams;
|
|
317
|
+
const type = searchParams.get("type");
|
|
318
|
+
if (type === "json") {
|
|
319
|
+
return CREATED({ accessToken, refreshToken });
|
|
320
|
+
}
|
|
321
|
+
const [accessTokenSetCookie, refreshTokenSetCookie] = await Promise.all([
|
|
322
|
+
authService.getAccessTokenSetCookie(accessToken),
|
|
323
|
+
authService.getRefreshTokenSetCookie(refreshToken)
|
|
324
|
+
]);
|
|
325
|
+
const payload = authService.jwtManager.decode(accessToken);
|
|
326
|
+
const headers = new Headers();
|
|
327
|
+
headers.append("Set-Cookie", accessTokenSetCookie);
|
|
328
|
+
headers.append("Set-Cookie", refreshTokenSetCookie);
|
|
329
|
+
return CREATED(payload, {
|
|
330
|
+
headers
|
|
331
|
+
});
|
|
320
332
|
};
|
|
321
333
|
|
|
322
334
|
// src/auth/handlers/signup_with_thirdparty.ts
|
|
@@ -369,10 +381,34 @@ var signUpWithThirdpartyHandler = async (request, {
|
|
|
369
381
|
return CREATED({ accessToken, refreshToken });
|
|
370
382
|
};
|
|
371
383
|
|
|
384
|
+
// src/auth/handlers/request_password_reset.ts
|
|
385
|
+
var requestPasswordResetHandler = async (request, {
|
|
386
|
+
passwordRecoveryService
|
|
387
|
+
}) => {
|
|
388
|
+
const { email } = await request.json();
|
|
389
|
+
try {
|
|
390
|
+
await passwordRecoveryService.requestPasswordReset(email);
|
|
391
|
+
return CREATED({ message: "\uBE44\uBC00\uBC88\uD638 \uC7AC\uC124\uC815 \uC774\uBA54\uC77C\uC744 \uC804\uC1A1\uD588\uC2B5\uB2C8\uB2E4." });
|
|
392
|
+
} catch (error) {
|
|
393
|
+
console.error(error);
|
|
394
|
+
return INTERNAL_SERVER_ERROR("\uC774\uBA54\uC77C \uC804\uC1A1\uC5D0 \uC2E4\uD328\uD588\uC2B5\uB2C8\uB2E4.");
|
|
395
|
+
}
|
|
396
|
+
};
|
|
397
|
+
|
|
398
|
+
// src/auth/handlers/reset_password.ts
|
|
399
|
+
var resetPasswordHandler = async (request, {
|
|
400
|
+
passwordRecoveryService
|
|
401
|
+
}) => {
|
|
402
|
+
const { token, password, passwordConfirm } = await request.json();
|
|
403
|
+
await passwordRecoveryService.resetPassword(token, password, passwordConfirm);
|
|
404
|
+
return NO_CONTENT();
|
|
405
|
+
};
|
|
406
|
+
|
|
372
407
|
// src/route/api.ts
|
|
373
408
|
var createAPIHandler = ({
|
|
374
409
|
authService,
|
|
375
410
|
fileService,
|
|
411
|
+
passwordRecoveryService,
|
|
376
412
|
getThirdPartyAuth,
|
|
377
413
|
signupTokenSecret
|
|
378
414
|
}) => {
|
|
@@ -468,6 +504,12 @@ var createAPIHandler = ({
|
|
|
468
504
|
}
|
|
469
505
|
}
|
|
470
506
|
}
|
|
507
|
+
case "request-password-reset": {
|
|
508
|
+
return requestPasswordResetHandler(request, { passwordRecoveryService });
|
|
509
|
+
}
|
|
510
|
+
case "reset-password": {
|
|
511
|
+
return resetPasswordHandler(request, { passwordRecoveryService });
|
|
512
|
+
}
|
|
471
513
|
}
|
|
472
514
|
}
|
|
473
515
|
case "files": {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dn-react-router-toolkit",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"types": "./dist/index.d.ts",
|
|
5
5
|
"main": "./dist/index.mjs",
|
|
6
6
|
"module": "./dist/index.js",
|
|
@@ -58,6 +58,7 @@
|
|
|
58
58
|
"description": "",
|
|
59
59
|
"devDependencies": {
|
|
60
60
|
"@types/node": "^24.10.1",
|
|
61
|
+
"@types/nodemailer": "^7.0.4",
|
|
61
62
|
"@types/react": "^19",
|
|
62
63
|
"@types/react-dom": "^19",
|
|
63
64
|
"rimraf": "^6.0.1",
|
|
@@ -71,6 +72,7 @@
|
|
|
71
72
|
"bcryptjs": "^3.0.3",
|
|
72
73
|
"jose": "^6.1.2",
|
|
73
74
|
"moment-timezone": "^0.6.0",
|
|
75
|
+
"nodemailer": "^7.0.11",
|
|
74
76
|
"react-icons": "^5.5.0",
|
|
75
77
|
"uuid": "^13.0.0"
|
|
76
78
|
},
|