create-craftjs 2.0.6 → 2.1.0
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/README.md +3 -0
- package/bin/index.js +10 -1
- package/package.json +5 -2
- package/template/Craft JS.postman_collection.json +1500 -0
- package/template/craft/commands/key-generate.js +12 -4
- package/template/craft/commands/make-controller.js +3 -3
- package/template/craft/commands/make-middleware.js +7 -7
- package/template/craft/commands/make-route.js +0 -3
- package/template/craft/commands/make-test.js +5 -4
- package/template/package-lock.json +95 -2
- package/template/package.json +3 -1
- package/template/src/config/database.ts +5 -3
- package/template/src/config/env.ts +10 -1
- package/template/src/config/logger.ts +2 -4
- package/template/src/config/redis.ts +77 -0
- package/template/src/config/web.ts +1 -1
- package/template/src/controllers/auth-controller.ts +22 -15
- package/template/src/controllers/user-controller.ts +1 -2
- package/template/src/database/seeders/seed.ts +14 -4
- package/template/src/dtos/auth-dto.ts +28 -0
- package/template/src/dtos/user-dto.ts +2 -5
- package/template/src/interfaces/auth-session.ts +16 -0
- package/template/src/interfaces/type-request.ts +11 -0
- package/template/src/main.ts +6 -4
- package/template/src/middleware/auth-middleware.ts +19 -28
- package/template/src/providers/auth-session-provider.ts +12 -0
- package/template/src/providers/db-auth-session.ts +23 -0
- package/template/src/providers/redis-auth-session.ts +33 -0
- package/template/src/repositories/auth-token-repository.ts +1 -1
- package/template/src/services/auth-service.ts +136 -78
- package/template/src/services/user-service.ts +8 -2
- package/template/test/user.test.ts +3 -2
- package/template/tsconfig.json +2 -1
- package/template/src/utils/type-request.ts +0 -6
package/template/src/main.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { web } from "
|
|
2
|
-
import { connectDatabase } from "
|
|
3
|
-
import { env } from "
|
|
4
|
-
import { logger } from "
|
|
1
|
+
import { web } from "@config/web";
|
|
2
|
+
import { connectDatabase } from "@config/database";
|
|
3
|
+
import { env } from "@config/env";
|
|
4
|
+
import { logger } from "@config/logger";
|
|
5
|
+
import { initRedis } from "@config/redis";
|
|
5
6
|
|
|
6
7
|
async function startServer() {
|
|
7
8
|
try {
|
|
@@ -11,6 +12,7 @@ async function startServer() {
|
|
|
11
12
|
process.exit(0);
|
|
12
13
|
}
|
|
13
14
|
await connectDatabase();
|
|
15
|
+
await initRedis();
|
|
14
16
|
web.listen(env.PORT, env.HOST, () => {
|
|
15
17
|
logger.info(`🚀 Server is listening on: http://${env.HOST}:${env.PORT}`);
|
|
16
18
|
logger.info(
|
|
@@ -1,51 +1,42 @@
|
|
|
1
1
|
import { NextFunction, Response } from "express";
|
|
2
2
|
import jwt from "jsonwebtoken";
|
|
3
|
-
import { UserRequest } from "@
|
|
4
|
-
import { errorResponse } from "@utils/response";
|
|
3
|
+
import { UserRequest } from "@interfaces/type-request";
|
|
5
4
|
import { ResponseError } from "@utils/response-error";
|
|
6
5
|
import { env } from "@config/env";
|
|
7
|
-
import { UserRepository } from "@repositories/user-repository";
|
|
8
6
|
import { asyncHandler } from "@utils/async-handler";
|
|
7
|
+
import { authSessionProvider } from "@providers/auth-session-provider";
|
|
9
8
|
|
|
10
9
|
export const authMiddleware = asyncHandler(
|
|
11
10
|
async (req: UserRequest, res: Response, next: NextFunction) => {
|
|
12
|
-
const cookie = req.cookies["refresh_token"];
|
|
13
|
-
if (!cookie) {
|
|
14
|
-
return res
|
|
15
|
-
.status(401)
|
|
16
|
-
.json(errorResponse("Unauthorized: Anda Belum Login.", 401));
|
|
17
|
-
}
|
|
18
|
-
|
|
19
11
|
const token = req.get("Authorization")?.split(" ")[1];
|
|
20
12
|
if (!token) {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
.
|
|
24
|
-
|
|
25
|
-
);
|
|
13
|
+
throw new ResponseError(
|
|
14
|
+
401,
|
|
15
|
+
"Unauthorized: Token Tidak Valid Atau Kadaluarsa."
|
|
16
|
+
);
|
|
26
17
|
}
|
|
27
|
-
|
|
18
|
+
const payload = jwt.verify(token, env.JWT_ACCESS_SECRET) as {
|
|
28
19
|
user_id: string;
|
|
29
|
-
|
|
30
|
-
user_full_name: string;
|
|
20
|
+
jti: string;
|
|
31
21
|
};
|
|
32
22
|
|
|
33
|
-
|
|
34
|
-
payload
|
|
35
|
-
|
|
23
|
+
const session = await authSessionProvider().get(
|
|
24
|
+
payload.user_id,
|
|
25
|
+
payload.jti
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
if (!session) {
|
|
36
29
|
throw new ResponseError(
|
|
37
30
|
401,
|
|
38
31
|
"Unauthorized: Token Tidak Valid Atau Kadaluarsa."
|
|
39
32
|
);
|
|
40
33
|
}
|
|
41
34
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
}
|
|
48
|
-
req.user = user;
|
|
35
|
+
req.user = {
|
|
36
|
+
...session,
|
|
37
|
+
jti: payload.jti,
|
|
38
|
+
};
|
|
39
|
+
|
|
49
40
|
next();
|
|
50
41
|
}
|
|
51
42
|
);
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { env } from "@config/env";
|
|
2
|
+
import { AuthSessionProvider } from "@interfaces/auth-session";
|
|
3
|
+
import { RedisAuthSessionProvider } from "@providers/redis-auth-session";
|
|
4
|
+
import { DbAuthSessionProvider } from "@providers/db-auth-session";
|
|
5
|
+
import { isRedisHealthy } from "@config/redis";
|
|
6
|
+
|
|
7
|
+
export const authSessionProvider = (): AuthSessionProvider => {
|
|
8
|
+
if (env.REDIS_ENABLED && isRedisHealthy()) {
|
|
9
|
+
return new RedisAuthSessionProvider();
|
|
10
|
+
}
|
|
11
|
+
return new DbAuthSessionProvider();
|
|
12
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { AuthSessionProvider } from "@interfaces/auth-session";
|
|
2
|
+
import { UserRepository } from "@repositories/user-repository";
|
|
3
|
+
|
|
4
|
+
export class DbAuthSessionProvider implements AuthSessionProvider {
|
|
5
|
+
async get(userId: string) {
|
|
6
|
+
const user = await UserRepository.findById(userId);
|
|
7
|
+
if (!user) return null;
|
|
8
|
+
|
|
9
|
+
return {
|
|
10
|
+
user_id: user.id,
|
|
11
|
+
user_email: user.email,
|
|
12
|
+
user_full_name: user.full_name,
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
async set() {
|
|
17
|
+
// no-op (DB fallback tidak simpan session)
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
async delete() {
|
|
21
|
+
// ❌ no-op
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { AuthSessionProvider } from "@interfaces/auth-session";
|
|
2
|
+
import { getRedis } from "@config/redis";
|
|
3
|
+
|
|
4
|
+
export class RedisAuthSessionProvider implements AuthSessionProvider {
|
|
5
|
+
async get(userId: string, jti: string) {
|
|
6
|
+
try {
|
|
7
|
+
const redis = getRedis();
|
|
8
|
+
const data = await redis.get(`session:${userId}:${jti}`);
|
|
9
|
+
return data ? JSON.parse(data) : null;
|
|
10
|
+
} catch {
|
|
11
|
+
return null;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
async set(userId: string, jti: string, data: any, ttl: number) {
|
|
16
|
+
try {
|
|
17
|
+
const redis = getRedis();
|
|
18
|
+
await redis.set(
|
|
19
|
+
`session:${userId}:${jti}`,
|
|
20
|
+
JSON.stringify(data),
|
|
21
|
+
"EX",
|
|
22
|
+
ttl
|
|
23
|
+
);
|
|
24
|
+
} catch {}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
async delete(userId: string, jti: string) {
|
|
28
|
+
try {
|
|
29
|
+
const redis = getRedis();
|
|
30
|
+
await redis.del(`session:${userId}:${jti}`);
|
|
31
|
+
} catch {}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
@@ -1,28 +1,27 @@
|
|
|
1
|
-
import {
|
|
2
|
-
toUserDetailResponse,
|
|
3
|
-
toUserResponse,
|
|
4
|
-
UserDetailResponse,
|
|
5
|
-
UserResponse,
|
|
6
|
-
loginRequest,
|
|
7
|
-
CreateUserRequest,
|
|
8
|
-
UpdateUserRequest,
|
|
9
|
-
} from "@dtos/user-dto";
|
|
1
|
+
import { toUserResponse, UserResponse } from "@dtos/user-dto";
|
|
10
2
|
import { ResponseError } from "@utils/response-error";
|
|
11
3
|
import { UserValidation } from "@validations/user-validation";
|
|
12
4
|
import { Validation } from "@utils/validation";
|
|
13
5
|
import * as argon2 from "argon2";
|
|
14
|
-
import { User } from "@prisma/client";
|
|
15
6
|
import jwt from "jsonwebtoken";
|
|
16
7
|
import { Request } from "express";
|
|
17
8
|
import { UserRepository } from "@repositories/user-repository";
|
|
18
|
-
import { UserRequest } from "@
|
|
19
|
-
import { prismaClient } from "@config/database";
|
|
9
|
+
import { UserRequest } from "@interfaces/type-request";
|
|
20
10
|
import { env } from "@config/env";
|
|
21
11
|
import { decryptCookie, encryptCookie } from "@utils/cookieEncrypt";
|
|
22
12
|
import { AuthTokenRepository } from "@repositories/auth-token-repository";
|
|
13
|
+
import { authSessionProvider } from "@providers/auth-session-provider";
|
|
14
|
+
import {
|
|
15
|
+
AuthUpdateRequest,
|
|
16
|
+
AuthMeResponse,
|
|
17
|
+
toAuthMeResponse,
|
|
18
|
+
LoginRequest,
|
|
19
|
+
RegisterRequest,
|
|
20
|
+
} from "@dtos/auth-dto";
|
|
21
|
+
const { v4: uuidv4 } = require("uuid");
|
|
23
22
|
|
|
24
23
|
export class AuthService {
|
|
25
|
-
static async register(request:
|
|
24
|
+
static async register(request: RegisterRequest): Promise<UserResponse> {
|
|
26
25
|
const data = Validation.validate(UserValidation.REGISTER, request);
|
|
27
26
|
const emailExits = await UserRepository.countByEmail(data.email);
|
|
28
27
|
|
|
@@ -40,94 +39,140 @@ export class AuthService {
|
|
|
40
39
|
return toUserResponse(response);
|
|
41
40
|
}
|
|
42
41
|
|
|
43
|
-
static async login(request:
|
|
42
|
+
static async login(request: LoginRequest) {
|
|
44
43
|
const data = Validation.validate(UserValidation.LOGIN, request);
|
|
45
|
-
const
|
|
44
|
+
const user = await UserRepository.findUserByEmail(data.email);
|
|
46
45
|
|
|
47
|
-
if (!
|
|
46
|
+
if (!user) {
|
|
48
47
|
throw new ResponseError(401, "Gagal Login! Detail login salah");
|
|
49
48
|
}
|
|
50
49
|
|
|
51
|
-
const isPasswordValid = await argon2.verify(
|
|
52
|
-
userExits.password,
|
|
53
|
-
data.password
|
|
54
|
-
);
|
|
50
|
+
const isPasswordValid = await argon2.verify(user.password, data.password);
|
|
55
51
|
if (!isPasswordValid) {
|
|
56
52
|
throw new ResponseError(401, "Gagal Login! Detail login salah");
|
|
57
53
|
}
|
|
58
|
-
|
|
59
|
-
const
|
|
54
|
+
const jti = uuidv4();
|
|
55
|
+
const accessToken = jwt.sign(
|
|
60
56
|
{
|
|
61
|
-
user_id:
|
|
62
|
-
|
|
63
|
-
user_email: userExits.email,
|
|
57
|
+
user_id: user.id,
|
|
58
|
+
jti: jti,
|
|
64
59
|
},
|
|
65
|
-
env.
|
|
60
|
+
env.JWT_ACCESS_SECRET as string,
|
|
66
61
|
{
|
|
67
|
-
expiresIn: "
|
|
62
|
+
expiresIn: "5m",
|
|
68
63
|
}
|
|
69
64
|
);
|
|
70
|
-
|
|
71
|
-
const accessToken = jwt.sign(
|
|
65
|
+
const refreshToken = jwt.sign(
|
|
72
66
|
{
|
|
73
|
-
user_id:
|
|
74
|
-
|
|
75
|
-
user_email: userExits.email,
|
|
67
|
+
user_id: user.id,
|
|
68
|
+
jti: jti,
|
|
76
69
|
},
|
|
77
|
-
env.
|
|
70
|
+
env.JWT_REFRESH_SECRET as string,
|
|
78
71
|
{
|
|
79
|
-
expiresIn: "
|
|
72
|
+
expiresIn: "1d",
|
|
80
73
|
}
|
|
81
74
|
);
|
|
75
|
+
const sessionProvider = authSessionProvider();
|
|
76
|
+
await sessionProvider.set(
|
|
77
|
+
user.id,
|
|
78
|
+
jti,
|
|
79
|
+
{
|
|
80
|
+
user_id: user.id,
|
|
81
|
+
user_email: user.email,
|
|
82
|
+
user_full_name: user.full_name,
|
|
83
|
+
},
|
|
84
|
+
300
|
|
85
|
+
);
|
|
82
86
|
const encryptedRefreshToken = encryptCookie(refreshToken);
|
|
83
87
|
await AuthTokenRepository.create({
|
|
84
|
-
user_id:
|
|
88
|
+
user_id: user.id,
|
|
85
89
|
token: refreshToken,
|
|
86
90
|
expires_at: new Date(Date.now() + 24 * 60 * 60 * 1000),
|
|
87
91
|
});
|
|
88
|
-
const
|
|
89
|
-
return {
|
|
92
|
+
const dataUser = toUserResponse(user);
|
|
93
|
+
return { dataUser, refreshToken: encryptedRefreshToken, accessToken };
|
|
90
94
|
}
|
|
91
95
|
|
|
92
|
-
static async me(
|
|
93
|
-
|
|
96
|
+
static async me(req: UserRequest): Promise<AuthMeResponse> {
|
|
97
|
+
if (!req.user) {
|
|
98
|
+
throw new ResponseError(401, "Unauthorized: Anda Belum Login.");
|
|
99
|
+
}
|
|
100
|
+
return toAuthMeResponse(req.user);
|
|
94
101
|
}
|
|
95
102
|
|
|
96
|
-
static async updateProfile(
|
|
97
|
-
user
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
const
|
|
101
|
-
|
|
102
|
-
|
|
103
|
+
static async updateProfile(req: UserRequest, request: AuthUpdateRequest) {
|
|
104
|
+
if (!req.user) {
|
|
105
|
+
throw new ResponseError(401, "Unauthorized : Anda Belum Login.");
|
|
106
|
+
}
|
|
107
|
+
const updateData: any = {};
|
|
108
|
+
const validatedData = Validation.validate(UserValidation.UPDATE, request);
|
|
109
|
+
if (validatedData.full_name) {
|
|
110
|
+
updateData.full_name = validatedData.full_name;
|
|
103
111
|
}
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
112
|
+
|
|
113
|
+
let emailChanged = false;
|
|
114
|
+
if (validatedData.email && validatedData.email !== req.user.user_email) {
|
|
115
|
+
const exists = await UserRepository.findemailExistsNotUserLoggedIn(
|
|
116
|
+
validatedData.email,
|
|
117
|
+
req.user.user_id
|
|
108
118
|
);
|
|
109
|
-
|
|
110
|
-
|
|
119
|
+
|
|
120
|
+
if (exists > 0) {
|
|
121
|
+
throw new ResponseError(409, "Email Sudah Terdaftar");
|
|
111
122
|
}
|
|
112
|
-
|
|
123
|
+
updateData.email = validatedData.email;
|
|
124
|
+
emailChanged = true;
|
|
113
125
|
}
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
},
|
|
119
|
-
user.id
|
|
126
|
+
|
|
127
|
+
const updatedUser = await UserRepository.update(
|
|
128
|
+
req.user.user_id,
|
|
129
|
+
updateData
|
|
120
130
|
);
|
|
121
|
-
|
|
131
|
+
if (emailChanged) {
|
|
132
|
+
const newJti = uuidv4();
|
|
133
|
+
const newAccessToken = jwt.sign(
|
|
134
|
+
{ user_id: req.user.user_id, jti: newJti },
|
|
135
|
+
env.JWT_ACCESS_SECRET as string,
|
|
136
|
+
{ expiresIn: "5m" }
|
|
137
|
+
);
|
|
138
|
+
|
|
139
|
+
const provider = authSessionProvider();
|
|
140
|
+
await provider.set(
|
|
141
|
+
req.user.user_id,
|
|
142
|
+
newJti,
|
|
143
|
+
{
|
|
144
|
+
...req.user,
|
|
145
|
+
user_email: updatedUser.email,
|
|
146
|
+
user_full_name: updatedUser.full_name,
|
|
147
|
+
},
|
|
148
|
+
300
|
|
149
|
+
);
|
|
150
|
+
|
|
151
|
+
await provider.delete(req.user.user_id, req.user.jti);
|
|
152
|
+
|
|
153
|
+
return {
|
|
154
|
+
rotated: true,
|
|
155
|
+
accessToken: newAccessToken,
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
return {
|
|
160
|
+
rotated: false,
|
|
161
|
+
};
|
|
122
162
|
}
|
|
123
163
|
|
|
124
164
|
static async logout(req: UserRequest) {
|
|
125
|
-
|
|
126
|
-
if (!req.user || !refreshToken) {
|
|
165
|
+
if (!req.user) {
|
|
127
166
|
throw new ResponseError(401, "Unauthorized: Anda Belum Login.");
|
|
128
167
|
}
|
|
129
|
-
const
|
|
130
|
-
await
|
|
168
|
+
const { user_id, jti } = req.user;
|
|
169
|
+
await authSessionProvider().delete(user_id, jti);
|
|
170
|
+
const encryptedRefreshToken = req.cookies.refresh_token;
|
|
171
|
+
|
|
172
|
+
if (encryptedRefreshToken) {
|
|
173
|
+
const refreshToken = decryptCookie(encryptedRefreshToken);
|
|
174
|
+
await AuthTokenRepository.revokeToken(refreshToken);
|
|
175
|
+
}
|
|
131
176
|
return true;
|
|
132
177
|
}
|
|
133
178
|
|
|
@@ -137,15 +182,19 @@ export class AuthService {
|
|
|
137
182
|
throw new ResponseError(401, "Unauthorized: Anda Belum Login.");
|
|
138
183
|
}
|
|
139
184
|
const refreshToken = decryptCookie(encryptedRefreshToken);
|
|
140
|
-
let decoded:
|
|
185
|
+
let decoded: { user_id: string; jti: string };
|
|
141
186
|
try {
|
|
142
|
-
decoded = jwt.verify(
|
|
143
|
-
|
|
187
|
+
decoded = jwt.verify(
|
|
188
|
+
refreshToken,
|
|
189
|
+
env.JWT_REFRESH_SECRET as string
|
|
190
|
+
) as typeof decoded;
|
|
191
|
+
} catch {
|
|
144
192
|
throw new ResponseError(
|
|
145
193
|
401,
|
|
146
194
|
"Unauthorized: Token Tidak Valid Atau Kadaluarsa."
|
|
147
195
|
);
|
|
148
196
|
}
|
|
197
|
+
|
|
149
198
|
const tokenRecord = await AuthTokenRepository.findValidToken(
|
|
150
199
|
decoded.user_id,
|
|
151
200
|
refreshToken
|
|
@@ -156,22 +205,31 @@ export class AuthService {
|
|
|
156
205
|
"Unauthorized: Token Tidak Valid Atau Kadaluarsa."
|
|
157
206
|
);
|
|
158
207
|
}
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
});
|
|
208
|
+
|
|
209
|
+
const user = await UserRepository.findById(decoded.user_id);
|
|
162
210
|
|
|
163
211
|
if (!user) {
|
|
164
212
|
throw new ResponseError(401, "Unauthorized: Uset Tidak Ditemukan.");
|
|
165
213
|
}
|
|
166
|
-
const
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
214
|
+
const newJti = uuidv4();
|
|
215
|
+
const accessToken = jwt.sign(
|
|
216
|
+
{ user_id: user.id, jti: newJti },
|
|
217
|
+
env.JWT_ACCESS_SECRET as string,
|
|
218
|
+
{ expiresIn: "5m" }
|
|
219
|
+
);
|
|
220
|
+
const provider = authSessionProvider();
|
|
221
|
+
|
|
222
|
+
await provider.set(
|
|
223
|
+
user.id,
|
|
224
|
+
newJti,
|
|
225
|
+
{
|
|
226
|
+
user_id: user.id,
|
|
227
|
+
user_email: user.email,
|
|
228
|
+
user_full_name: user.full_name,
|
|
229
|
+
},
|
|
230
|
+
300
|
|
231
|
+
);
|
|
171
232
|
|
|
172
|
-
const accessToken = jwt.sign(payload, env.JWT_SECRET as string, {
|
|
173
|
-
expiresIn: "5m",
|
|
174
|
-
});
|
|
175
233
|
return { accessToken };
|
|
176
234
|
}
|
|
177
235
|
}
|
|
@@ -26,7 +26,7 @@ export class UserService {
|
|
|
26
26
|
data.password = await argon2.hash(data.password);
|
|
27
27
|
|
|
28
28
|
const response = await UserRepository.create({
|
|
29
|
-
|
|
29
|
+
full_name: data.full_name,
|
|
30
30
|
email: data.email,
|
|
31
31
|
password: data.password,
|
|
32
32
|
});
|
|
@@ -117,9 +117,15 @@ export class UserService {
|
|
|
117
117
|
}
|
|
118
118
|
user.email = data.email;
|
|
119
119
|
}
|
|
120
|
+
|
|
121
|
+
if (data.password) {
|
|
122
|
+
user.password = await argon2.hash(data.password);
|
|
123
|
+
}
|
|
124
|
+
|
|
120
125
|
const result = await UserRepository.update(id, {
|
|
121
|
-
|
|
126
|
+
full_name: user.full_name,
|
|
122
127
|
email: user.email,
|
|
128
|
+
password: user.password,
|
|
123
129
|
});
|
|
124
130
|
return toUserResponse(result);
|
|
125
131
|
}
|
|
@@ -1,12 +1,13 @@
|
|
|
1
|
+
/// <reference types="jest" />
|
|
1
2
|
import supertest from "supertest";
|
|
2
3
|
import { web } from "../src/config/web";
|
|
3
4
|
import { logger } from "../src/config/logger";
|
|
4
|
-
describe("POST /api/
|
|
5
|
+
describe("POST /api/auth/register", () => {
|
|
5
6
|
it("should register new user", async () => {
|
|
6
7
|
const response = await supertest(web).post("/api/auth/register").send({
|
|
7
8
|
full_name: "test",
|
|
8
9
|
email: "testing@gmail.com",
|
|
9
|
-
password: "
|
|
10
|
+
password: "123456",
|
|
10
11
|
});
|
|
11
12
|
logger.debug(response.body);
|
|
12
13
|
expect(response.status).toBe(201);
|
package/template/tsconfig.json
CHANGED
|
@@ -9,9 +9,10 @@
|
|
|
9
9
|
"@services/*": ["./src/services/*"],
|
|
10
10
|
"@repositories/*": ["./src/repositories/*"],
|
|
11
11
|
"@routes/*": ["./src/routes/*"],
|
|
12
|
+
"@interfaces/*": ["./src/interfaces/*"],
|
|
12
13
|
"@middleware/*": ["./src/middleware/*"],
|
|
14
|
+
"@providers/*": ["./src/providers/*"],
|
|
13
15
|
"@dtos/*": ["./src/dtos/*"],
|
|
14
|
-
"@types/*": ["./src/types/*"],
|
|
15
16
|
"@utils/*": ["./src/utils/*"],
|
|
16
17
|
"@validations/*": ["./src/validations/*"],
|
|
17
18
|
"@views/*": ["./src/views/*"],
|