Skip to content

Commit 0d61e46

Browse files
committed
Merge branch '#159-add-typescript-support' of https://github.com/sparcs-kaist/taxi-back into #159-add-typescript-support
2 parents 3ce5406 + 7e17d5f commit 0d61e46

File tree

14 files changed

+95
-92
lines changed

14 files changed

+95
-92
lines changed

scripts/profileImageUrlUpdater.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// https://github.com/sparcs-kaist/taxi-back/issues/173
33

44
const { MongoClient } = require("mongodb");
5-
const { mongo: mongoUrl, aws: awsEnv } = require("../loadenv"); // FIXME: 올바른 경로로 수정해야 합니다.
5+
const { mongoUrl, aws: awsEnv } = require("../loadenv"); // FIXME: 올바른 경로로 수정해야 합니다.
66

77
const time = Date.now();
88

src/index.ts

+5-5
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import express from "express";
33
import cookieParser from "cookie-parser";
44
import http from "http";
55

6-
import { nodeEnv, mongo as mongoUrl, port as httpPort } from "@/loadenv";
6+
import config from "@/loadenv";
77
import {
88
corsMiddleware,
99
sessionMiddleware,
@@ -40,14 +40,14 @@ initializeApp();
4040
const app = express();
4141

4242
// 데이터베이스 연결
43-
connectDatabase(mongoUrl);
43+
connectDatabase(config.mongoUrl);
4444

4545
// [Middleware] request body 파싱
4646
app.use(express.urlencoded({ extended: false }));
4747
app.use(express.json());
4848

4949
// reverse proxy가 설정한 헤더를 신뢰합니다.
50-
if (nodeEnv === "production") app.set("trust proxy", 2);
50+
if (config.nodeEnv === "production") app.set("trust proxy", 2);
5151

5252
// [Middleware] CORS 설정
5353
app.use(corsMiddleware);
@@ -95,8 +95,8 @@ app.use(errorHandler);
9595
// express 서버 시작
9696
const serverHttp = http
9797
.createServer(app)
98-
.listen(httpPort, () =>
99-
logger.info(`Express server started from port ${httpPort}`)
98+
.listen(config.port, () =>
99+
logger.info(`Express server started from port ${config.port}`)
100100
);
101101

102102
// socket.io 서버 시작

src/loadenv.ts

+51-47
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import dotenv from "dotenv";
33
import { type Algorithm } from "jsonwebtoken";
44
import { type ServiceAccount } from "firebase-admin";
5+
import exp from "constants";
56

67
if (process.env.NODE_ENV === undefined) {
78
// logger.ts가 아직 초기화되지 않았으므로 console.error를 사용합니다.
@@ -18,52 +19,55 @@ if (process.env.DB_PATH === undefined) {
1819
process.exit(1);
1920
}
2021

21-
export const nodeEnv = process.env.NODE_ENV; // required ("production" or "development" or "test")
22-
export const mongo = process.env.DB_PATH; // required
23-
export const session = {
24-
secret: process.env.SESSION_KEY || "TAXI_SESSION_KEY", // optional
25-
expiry: 14 * 24 * 3600 * 1000, // 14일, ms 단위입니다.
26-
};
27-
export const redis = process.env.REDIS_PATH; // optional
28-
export const sparcssso = {
29-
id: process.env.SPARCSSSO_CLIENT_ID || "", // optional
30-
key: process.env.SPARCSSSO_CLIENT_KEY || "", // optional
31-
};
32-
export const port = process.env.PORT ? parseInt(process.env.PORT) : 80; // optional (default = 80)
33-
export const corsWhiteList = (process.env.CORS_WHITELIST &&
34-
(JSON.parse(process.env.CORS_WHITELIST) as string[])) || [true]; // optional (default = [true])
35-
export const aws = {
36-
accessKeyId: process.env.AWS_ACCESS_KEY_ID as string, // required
37-
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY as string, // required
38-
s3BucketName: process.env.AWS_S3_BUCKET_NAME as string, // required
39-
s3Url:
40-
process.env.AWS_S3_URL ||
41-
`https://${process.env.AWS_S3_BUCKET_NAME}.s3.ap-northeast-2.amazonaws.com`, // optional
42-
};
43-
export const jwt = {
44-
secretKey: process.env.JWT_SECRET_KEY || "TAXI_JWT_KEY",
45-
option: {
46-
algorithm: "HS256" as Algorithm,
47-
// FIXME: remove FRONT_URL from issuer. 단, issuer를 변경하면 이전에 발급했던 모든 JWT가 무효화됩니다.
48-
// See https://github.com/sparcs-kaist/taxi-back/issues/415
49-
issuer: process.env.FRONT_URL || "http://localhost:3000", // optional (default = "http://localhost:3000")
22+
const config = {
23+
nodeEnv: process.env.NODE_ENV,
24+
mongoUrl: process.env.DB_PATH,
25+
session: {
26+
secret: process.env.SESSION_KEY || "TAXI_SESSION_KEY",
27+
expiry: 14 * 24 * 3600 * 1000,
28+
},
29+
redisUrl: process.env.REDIS_PATH,
30+
sparcssso: {
31+
id: process.env.SPARCSSSO_CLIENT_ID || "",
32+
key: process.env.SPARCSSSO_CLIENT_KEY || "",
33+
},
34+
port: process.env.PORT ? parseInt(process.env.PORT) : 80,
35+
corsWhiteList: (process.env.CORS_WHITELIST &&
36+
(JSON.parse(process.env.CORS_WHITELIST) as string[])) || [true],
37+
aws: {
38+
accessKeyId: process.env.AWS_ACCESS_KEY_ID as string,
39+
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY as string,
40+
s3BucketName: process.env.AWS_S3_BUCKET_NAME as string,
41+
s3Url:
42+
process.env.AWS_S3_URL ||
43+
`https://${process.env.AWS_S3_BUCKET_NAME}.s3.ap-northeast-2.amazonaws.com`,
44+
},
45+
jwt: {
46+
secretKey: process.env.JWT_SECRET || "TAXI_JWT_KEY",
47+
option: {
48+
algorithm: "HS256" as Algorithm,
49+
// FIXME: remove FRONT_URL from issuer. 단, issuer를 변경하면 이전에 발급했던 모든 JWT가 무효화됩니다.
50+
// See https://github.com/sparcs-kaist/taxi-back/issues/415
51+
issuer: process.env.FRONT_URL || "http://localhost:3000",
52+
},
53+
TOKEN_EXPIRED: -3,
54+
TOKEN_INVALID: -2,
55+
},
56+
57+
googleApplicationCredentials:
58+
process.env.GOOGLE_APPLICATION_CREDENTIALS &&
59+
(JSON.parse(process.env.GOOGLE_APPLICATION_CREDENTIALS) as ServiceAccount),
60+
testAccounts:
61+
(process.env.TEST_ACCOUNTS &&
62+
(JSON.parse(process.env.TEST_ACCOUNTS) as string[])) ||
63+
[],
64+
slackWebhookUrl: {
65+
report: process.env.SLACK_REPORT_WEBHOOK_URL || "",
66+
},
67+
naverMap: {
68+
apiId: process.env.NAVER_MAP_API_ID || "",
69+
apiKey: process.env.NAVER_MAP_API_KEY || "",
5070
},
51-
TOKEN_EXPIRED: -3,
52-
TOKEN_INVALID: -2,
53-
};
54-
export const googleApplicationCredentials =
55-
process.env.GOOGLE_APPLICATION_CREDENTIALS &&
56-
(JSON.parse(process.env.GOOGLE_APPLICATION_CREDENTIALS) as ServiceAccount); // optional
57-
export const testAccounts =
58-
(process.env.TEST_ACCOUNTS &&
59-
(JSON.parse(process.env.TEST_ACCOUNTS) as string[])) ||
60-
[]; // optional
61-
export const slackWebhookUrl = {
62-
report: process.env.SLACK_REPORT_WEBHOOK_URL || "", // optional
63-
};
64-
// export const eventConfig =
65-
// process.env.EVENT_CONFIG && JSON.parse(process.env.EVENT_CONFIG); // optional
66-
export const naverMap = {
67-
apiId: process.env.NAVER_MAP_API_ID || "", // optional
68-
apiKey: process.env.NAVER_MAP_API_KEY || "", // optional
6971
};
72+
73+
export default config;

src/middlewares/cors.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import cors from "cors";
2-
import { corsWhiteList } from "@/loadenv";
2+
import config from "@/loadenv";
33

44
const corsMiddleware = cors({
5-
origin: corsWhiteList,
5+
origin: config.corsWhiteList,
66
credentials: true,
77
exposedHeaders: ["Date"],
88
});

src/middlewares/session.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import expressSession from "express-session";
2-
import { nodeEnv, session as sessionConfig } from "@/loadenv";
2+
import config from "@/loadenv";
33
import type { LoginInfo } from "@/modules/auths/login";
44
import sessionStore from "@/modules/stores/sessionStore";
55

@@ -26,14 +26,14 @@ declare module "express-session" {
2626
}
2727

2828
const sessionMiddleware = expressSession({
29-
secret: sessionConfig.secret,
29+
secret: config.session.secret,
3030
resave: false,
3131
saveUninitialized: false,
3232
store: sessionStore,
3333
cookie: {
34-
maxAge: sessionConfig.expiry,
34+
maxAge: config.session.expiry,
3535
// nodeEnv가 production일 때만 secure cookie를 사용합니다.
36-
secure: nodeEnv === "production",
36+
secure: config.nodeEnv === "production",
3737
},
3838
});
3939

src/modules/auths/jwt.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import jwt, { type SignOptions } from "jsonwebtoken";
2-
import { jwt as jwtConfig } from "@/loadenv";
2+
import config from "@/loadenv";
33

4-
const { secretKey, option, TOKEN_EXPIRED, TOKEN_INVALID } = jwtConfig;
4+
const { secretKey, option, TOKEN_EXPIRED, TOKEN_INVALID } = config.jwt;
55

66
type TokenType = "access" | "refresh";
77

src/modules/auths/login.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { type Request } from "express";
2-
import { session as sessionConfig } from "@/loadenv";
2+
import config from "@/loadenv";
33
import logger from "@/modules/logger";
44

55
export interface LoginInfo {
@@ -16,7 +16,7 @@ export const getLoginInfo = (req: Request) => {
1616
const timeFlow = Date.now() - time;
1717
// 14일이 지난 세션에 대해서는 로그인 정보를 반환하지 않습니다.
1818
// 세션은 새로운 요청 시 갱신되지 않습니다.
19-
if (timeFlow > sessionConfig.expiry) {
19+
if (timeFlow > config.session.expiry) {
2020
return { id: undefined, sid: undefined, oid: undefined, name: undefined };
2121
}
2222
return { id, sid, oid, name };

src/modules/fcm.ts

+5-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import firebaseAdmin from "firebase-admin";
22
import { type SendResponse, getMessaging } from "firebase-admin/messaging";
3-
import { googleApplicationCredentials } from "@/loadenv";
3+
import config from "@/loadenv";
44
import logger from "@/modules/logger";
55
import {
66
deviceTokenModel,
@@ -13,9 +13,11 @@ import { type ChatType } from "@/types/mongo";
1313
* credential을 등록합니다.
1414
*/
1515
export const initializeApp = () => {
16-
if (googleApplicationCredentials) {
16+
if (config.googleApplicationCredentials) {
1717
firebaseAdmin.initializeApp({
18-
credential: firebaseAdmin.credential.cert(googleApplicationCredentials),
18+
credential: firebaseAdmin.credential.cert(
19+
config.googleApplicationCredentials
20+
),
1921
});
2022
} else {
2123
logger.error(

src/modules/logger.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import path from "path";
22
import { createLogger, format, transports } from "winston";
33
import DailyRotateFileTransport from "winston-daily-rotate-file";
44

5-
import { nodeEnv } from "@/loadenv";
5+
import config from "@/loadenv";
66

77
// logger에서 사용할 포맷들을 정의합니다.
88
const baseFormat = format.combine(
@@ -50,7 +50,7 @@ const consoleTransport = new transports.Console();
5050
* @method error(message: string, callback: winston.LogCallback) - 오류 메시지를 기록하기 위해 사용합니다.
5151
*/
5252
const logger =
53-
nodeEnv === "production"
53+
config.nodeEnv === "production"
5454
? // "production" 환경에서 사용되는 Logger 객체
5555
createLogger({
5656
level: "info",

src/modules/slackNotification.ts

+6-5
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,19 @@
11
import axios from "axios";
2-
import { nodeEnv, slackWebhookUrl as slackUrl } from "@/loadenv";
2+
import config from "@/loadenv";
33
import logger from "@/modules/logger";
44
import { type Report } from "@/types/mongo";
55

66
export const sendTextToReportChannel = (text: string) => {
7-
if (!slackUrl.report) return;
7+
if (!config.slackWebhookUrl.report) return;
88

99
const data = {
10-
text: nodeEnv === "production" ? text : `(${nodeEnv}) ${text}`, // Production 환경이 아닌 경우, 환경 이름을 붙여서 전송합니다.
10+
text:
11+
config.nodeEnv === "production" ? text : `(${config.nodeEnv}) ${text}`, // Production 환경이 아닌 경우, 환경 이름을 붙여서 전송합니다.
1112
};
12-
const config = { headers: { "Content-Type": "application/json" } };
13+
const axiosConfig = { headers: { "Content-Type": "application/json" } };
1314

1415
axios
15-
.post(slackUrl.report, data, config)
16+
.post(config.slackWebhookUrl.report, data, axiosConfig)
1617
.then(() => {
1718
logger.info("Slack webhook sent successfully");
1819
})

src/modules/stores/aws.ts

+7-7
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import AWS from "aws-sdk";
2-
import { aws as awsEnv } from "@/loadenv";
2+
import config from "@/loadenv";
33

44
AWS.config.update({
55
region: "ap-northeast-2",
@@ -16,7 +16,7 @@ export const getList = (
1616
) => {
1717
s3.listObjects(
1818
{
19-
Bucket: awsEnv.s3BucketName,
19+
Bucket: config.aws.s3BucketName,
2020
Prefix: directoryPath,
2121
},
2222
(err, data) => {
@@ -31,7 +31,7 @@ export const getUploadPUrlPut = (
3131
contentType: string = "image/png"
3232
) => {
3333
const presignedUrl = s3.getSignedUrl("putObject", {
34-
Bucket: awsEnv.s3BucketName,
34+
Bucket: config.aws.s3BucketName,
3535
Key: filePath,
3636
ContentType: contentType,
3737
Expires: 60, // 1 min
@@ -47,7 +47,7 @@ export const getUploadPUrlPost = (
4747
) => {
4848
s3.createPresignedPost(
4949
{
50-
Bucket: awsEnv.s3BucketName,
50+
Bucket: config.aws.s3BucketName,
5151
Expires: 60, // 1 min
5252
Conditions: [
5353
{ key: filePath },
@@ -68,7 +68,7 @@ export const deleteObject = (
6868
) => {
6969
s3.deleteObject(
7070
{
71-
Bucket: awsEnv.s3BucketName,
71+
Bucket: config.aws.s3BucketName,
7272
Key: filePath,
7373
},
7474
(err, data) => {
@@ -84,7 +84,7 @@ export const foundObject = (
8484
) => {
8585
s3.headObject(
8686
{
87-
Bucket: awsEnv.s3BucketName,
87+
Bucket: config.aws.s3BucketName,
8888
Key: filePath,
8989
},
9090
(err, data) => {
@@ -95,5 +95,5 @@ export const foundObject = (
9595

9696
// function to return full URL of the object
9797
export const getS3Url = (filePath: string) => {
98-
return `${awsEnv.s3Url}${filePath}`;
98+
return `${config.aws.s3Url}${filePath}`;
9999
};

src/modules/stores/sessionStore.ts

+5-9
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,14 @@
11
import MongoStore from "connect-mongo";
22
import RedisStore from "connect-redis";
33
import redis from "redis";
4-
import {
5-
redis as redisUrl,
6-
mongo as mongoUrl,
7-
session as sessionConfig,
8-
} from "@/loadenv";
4+
import config from "@/loadenv";
95
import logger from "@/modules/logger";
106

117
const getSessionStore = () => {
128
// 환경변수 REDIS_PATH 유무에 따라 session 저장 방식이 변경됩니다.
13-
if (redisUrl) {
9+
if (config.redisUrl) {
1410
const client = redis.createClient({
15-
url: redisUrl,
11+
url: config.redisUrl,
1612
});
1713

1814
// redis client 연결 성공 시 로그를 출력합니다.
@@ -26,9 +22,9 @@ const getSessionStore = () => {
2622
});
2723

2824
client.connect().catch(logger.error);
29-
return new RedisStore({ client, ttl: sessionConfig.expiry });
25+
return new RedisStore({ client, ttl: config.session.expiry });
3026
} else {
31-
return MongoStore.create({ mongoUrl });
27+
return MongoStore.create({ mongoUrl: config.mongoUrl });
3228
}
3329
};
3430

src/sampleGenerator/index.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ const {
55
generateChats,
66
} = require("./src/testData");
77
const { connectDatabase } = require("../modules/stores/mongo");
8-
const { mongo: mongoUrl, numberOfChats, numberOfRooms } = require("./loadenv");
8+
const { mongoUrl, numberOfChats, numberOfRooms } = require("./loadenv");
99

1010
const database = connectDatabase(mongoUrl);
1111

0 commit comments

Comments
 (0)