Skip to content

Commit

Permalink
Merge pull request #211 from sparcs-kaist/dev
Browse files Browse the repository at this point in the history
Main branch update from Dev branch
  • Loading branch information
14KGun authored Jan 18, 2023
2 parents 8ac0eea + 4cbf55c commit c9cc14c
Show file tree
Hide file tree
Showing 15 changed files with 364 additions and 51 deletions.
14 changes: 13 additions & 1 deletion .github/workflows/test_ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
branches: [ "main", "dev" ]
jobs:
build:
runs-on: ubuntu-latest
Expand All @@ -26,6 +26,18 @@ jobs:
with:
node-version: ${{ matrix.node-version }}
cache: 'npm'
- id: submodule-local
name: Save local version of submodule
run: echo "ver=`cd sampleGenerator && git log --pretty="%h" -1 && cd ..`" >> $GITHUB_OUTPUT
- id: submodule-origin
name: Save origin version of submodule
run: echo "ver=`cd sampleGenerator && git log origin --pretty="%h" -1 && cd ..`" >> $GITHUB_OUTPUT
- name: Check submodule version
if: ${{ steps.submodule-local.outputs.ver != steps.submodule-origin.outputs.ver }}
uses: actions/github-script@v3
with:
script: |
core.setFailed('Please update submodule to the latest version by using \"git submodule update --remote\"')
- name: Install sampleGenerator dependencies from package-lock.json
run: cd sampleGenerator && npm ci && cd ..
- name: Install taxi-back dependencies from package-lock.json
Expand Down
1 change: 1 addition & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
[submodule "sampleGenerator"]
path = sampleGenerator
url = https://github.com/sparcs-kaist/taxiSampleGenerator
branch = main
2 changes: 1 addition & 1 deletion sampleGenerator
10 changes: 10 additions & 0 deletions src/db/mongo.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ const userSchema = Schema({
},
email: { type: String, required: true },
isAdmin: { type: Boolean, default: false }, //관리자 여부
account: { type: String, default: "" }, //계좌번호 정보
});

const participantSchema = Schema({
Expand Down Expand Up @@ -93,6 +94,11 @@ const reportSchema = Schema({
time: { type: Date, required: true },
});

const adminIPWhitelistSchema = Schema({
ip: { type: String, required: true }, // IP 주소
description: { type: String, default: "" }, // 설명
});

const database = mongoose.connection;
database.on("error", console.error.bind(console, "mongoose connection error."));
database.on("open", () => {
Expand Down Expand Up @@ -125,4 +131,8 @@ module.exports = {
locationModel: mongoose.model("Location", locationSchema),
chatModel: mongoose.model("Chat", chatSchema),
reportModel: mongoose.model("Report", reportSchema),
adminIPWhitelistModel: mongoose.model(
"AdminIPWhitelist",
adminIPWhitelistSchema
),
};
1 change: 1 addition & 0 deletions src/db/patterns.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ module.exports = {
nickname: RegExp("^[A-Za-z가-힣ㄱ-ㅎㅏ-ㅣ0-9-_ ]{3,25}$"),
allowedEmployeeTypes: RegExp("^([PEUR]|[SA]|[PEUR][SA])$"),
profileImgType: RegExp("^(image/png|image/jpg|image/jpeg)$"),
account: RegExp("^[A-Za-z가-힣]{2,7} [0-9]{10,14}$"),
},
chat: {
chatImgType: RegExp("^(image/png|image/jpg|image/jpeg)$"),
Expand Down
30 changes: 19 additions & 11 deletions src/middleware/adminAuth.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,30 @@

const { isLogin, getLoginInfo } = require("../auth/login");
const { frontUrl } = require("../../security");
const { userModel } = require("../db/mongo");
const { userModel, adminIPWhitelistModel } = require("../db/mongo");

const adminAuthMiddleware = async (req, res, next) => {
// Check if user is logged in
if (!isLogin(req)) {
res.redirect(frontUrl);
return;
}
try {
// 로그인 여부를 확인
if (!isLogin(req)) return res.redirect(frontUrl);

// 관리자 유무를 확인
const { id } = getLoginInfo(req);
const user = await userModel.findOne({ id });
if (user.isAdmin) {
next();
} else {
res.redirect(frontUrl);
}
if (!user.isAdmin) return res.redirect(frontUrl);

// 접속한 IP가 화이트리스트에 있는지 확인
const clientIP =
req.headers["x-forwarded-for"] || req.connection.remoteAddress;
const ipWhitelist = await adminIPWhitelistModel.find({});
if (!clientIP) return res.redirect(frontUrl);
if (
ipWhitelist.length > 0 &&
ipWhitelist.map((x) => x.ip).indexOf(clientIP) < 0
)
return res.redirect(frontUrl);

next();
} catch (e) {
res.redirect(frontUrl);
}
Expand Down
10 changes: 9 additions & 1 deletion src/route/admin.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ const {
locationModel,
chatModel,
reportModel,
adminIPWhitelistModel,
} = require("../db/mongo");

let router = express.Router();
Expand All @@ -20,7 +21,14 @@ AdminJS.registerAdapter(AdminJSMongoose);

// Create router for admin page
const adminJsOptions = {
resources: [userModel, roomModel, locationModel, chatModel, reportModel],
resources: [
userModel,
roomModel,
locationModel,
chatModel,
reportModel,
adminIPWhitelistModel,
],
};
const adminJs = new AdminJS(adminJsOptions);
router = AdminJSExpress.buildRouter(adminJs, router);
Expand Down
8 changes: 8 additions & 0 deletions src/route/users.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,14 @@ router.post(
userHandlers.editNicknameHandler
);

// 새 계좌번호를 받아 로그인된 유저의 계좌번호를 변경합니다.
router.post(
"/editAccount",
body("account").matches(patterns.user.account),
validator,
userHandlers.editAccountHandler
);

// 프로필 이미지를 업로드할 수 있는 Presigned-url을 발급합니다.
router.post(
"/editProfileImg/getPUrl",
Expand Down
49 changes: 24 additions & 25 deletions src/service/logininfo.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,32 +8,31 @@ const logininfoHandler = (req, res) => {

const detailHandler = (req, res) => {
const user = getLoginInfo(req);

if (user.id) {
userModel.findOne(
{ id: user.id },
"_id name nickname id withdraw ban joinat agreeOnTermsOfService subinfo email profileImageUrl",
(err, result) => {
if (err) res.json({ err: true });
else if (!result) res.json({ err: true });
else {
res.json({
oid: result._id,
id: result.id,
name: result.name,
nickname: result.nickname,
withdraw: result.withdraw,
ban: result.ban,
joinat: result.joinat,
agreeOnTermsOfService: result.agreeOnTermsOfService,
subinfo: result.subinfo,
email: result.email,
profileImgUrl: result.profileImageUrl,
});
}
if (!user.id) return res.json({ id: undefined });
userModel.findOne(
{ id: user.id },
"_id name nickname id withdraw ban joinat agreeOnTermsOfService subinfo email profileImageUrl",
(err, result) => {
if (err) res.json({ err: true });
else if (!result) res.json({ err: true });
else {
res.json({
oid: result._id,
id: result.id,
name: result.name,
nickname: result.nickname,
withdraw: result.withdraw,
ban: result.ban,
joinat: result.joinat,
agreeOnTermsOfService: result.agreeOnTermsOfService,
subinfo: result.subinfo,
email: result.email,
profileImgUrl: result.profileImageUrl,
account: result.account ? result.account : "",
});
}
);
} else res.json({ id: undefined });
}
);
};

module.exports = {
Expand Down
20 changes: 20 additions & 0 deletions src/service/users.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,25 @@ const editNicknameHandler = (req, res) => {
});
};

const editAccountHandler = (req, res) => {
const newAccount = req.body.account;

// 계좌번호를 갱신하고 결과를 반환
userModel
.findOneAndUpdate({ id: req.userId }, { account: newAccount })
.then((result) => {
if (result) {
res.status(200).send("User/editAccount : edit user account successful");
} else {
res.status(400).send("User/editAccount : such user id does not exist");
}
})
.catch((err) => {
logger.error(err);
res.status(500).send("User/editAccount : internal server error");
});
};

const editProfileImgGetPUrlHandler = async (req, res) => {
try {
const type = req.body.type;
Expand Down Expand Up @@ -122,6 +141,7 @@ module.exports = {
agreeOnTermsOfServiceHandler,
getAgreeOnTermsOfServiceHandler,
editNicknameHandler,
editAccountHandler,
editProfileImgGetPUrlHandler,
editProfileImgDoneHandler,
};
4 changes: 2 additions & 2 deletions test/auth.replace.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@ const authHandlers = require("../src/service/auth.replace");
const { userModel } = require("../src/db/mongo");
const security = require("../security");

describe("auth.replace handler", function () {
describe("[auth.replace] 1.sparcsssoHandler", () => {
const removeTestUser = async () => {
// drop all collections
await userModel.deleteOne({ id: "test" });
};

before(removeTestUser);

it("should redirect to security.frontUrl after successful user creation", function () {
it("should redirect to security.frontUrl after successful user creation", () => {
request(authHandlers.sparcsssoHandler)
.post("/auth/sparcssso")
.send({
Expand Down
4 changes: 2 additions & 2 deletions test/locations.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
const expect = require("chai").expect;
const locationHandlers = require("../src/service/locations");

describe("locations handler", function () {
it("should return information of locations correctly", async function () {
describe("[locations] 1.getAllLocationsHandler", () => {
it("should return information of locations correctly", async () => {
const req = {};
const res = {
json: (data) => {
Expand Down
17 changes: 9 additions & 8 deletions test/logininfo.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ const expect = require("chai").expect;
const logininfoHandlers = require("../src/service/logininfo");
const { userModel } = require("../src/db/mongo");

describe("logininfo handler", function () {
it("should return {id: undefined, sid: undefined, name: undefined } when no user is logged in", function () {
describe("[logininfo] 1.logininfoHandler", () => {
it("should return {id: undefined, sid: undefined, name: undefined } when no user is logged in", () => {
const req = { session: {} };
const res = {
json: (data) => {
Expand All @@ -17,7 +17,7 @@ describe("logininfo handler", function () {
logininfoHandlers.logininfoHandler(req, res);
});

it("should return {id: 'hello-id', sid: 'hello-sid', 'name': 'hello-name'} when user is logged in", function () {
it("should return {id: 'hello-id', sid: 'hello-sid', 'name': 'hello-name'} when user is logged in", () => {
const req = {
session: {
loginInfo: {
Expand All @@ -40,7 +40,7 @@ describe("logininfo handler", function () {
logininfoHandlers.logininfoHandler(req, res);
});

it("should return {id: undefined, sid: undefined, name: undefined } when the session is expired", function () {
it("should return {id: undefined, sid: undefined, name: undefined } when the session is expired", () => {
const req = {
session: {
loginInfo: {
Expand All @@ -64,8 +64,8 @@ describe("logininfo handler", function () {
});
});

describe("detail info handler", function () {
it("should return { id: undefined } when no user is logged in", function () {
describe("[logininfo] 2.detailHandler", () => {
it("should return { id: undefined } when no user is logged in", () => {
const req = { session: {} };
const res = {
json: (data) => {
Expand All @@ -77,7 +77,7 @@ describe("detail info handler", function () {
logininfoHandlers.detailHandler(req, res);
});

it("should return correct information as same as user's when user is logged in", async function () {
it("should return correct information as same as user's when user is logged in", async () => {
const req = {
session: {
loginInfo: {
Expand Down Expand Up @@ -106,13 +106,14 @@ describe("detail info handler", function () {
subinfo: result.subinfo,
email: result.email,
profileImgUrl: result.profileImageUrl,
account: "",
});
},
};
logininfoHandlers.detailHandler(req, res);
});

it("should return {id: undefined} when the session is expired", function () {
it("should return {id: undefined} when the session is expired", () => {
const req = {
session: {
loginInfo: {
Expand Down
Loading

0 comments on commit c9cc14c

Please sign in to comment.