Skip to content

Commit

Permalink
Refactor: ensure user is logged out immediately upon withdrawal
Browse files Browse the repository at this point in the history
  • Loading branch information
kmc7468 committed Jan 22, 2025
1 parent aff0f86 commit 4d63ff8
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 17 deletions.
9 changes: 8 additions & 1 deletion src/modules/auths/login.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
import type { Request } from "express";
import { session as sessionConfig } from "@/loadenv";
import { session as sessionConfig, sparcssso as sparcsssoEnv } from "@/loadenv";
import logger from "@/modules/logger";
import SsoClient from "./sparcssso";

// 환경변수 SPARCSSSO_CLIENT_ID 유무에 따라 로그인 방식이 변경됩니다.
export const isAuthReplace = !sparcsssoEnv.id;
export const ssoClient = !isAuthReplace
? new SsoClient(sparcsssoEnv.id, sparcsssoEnv.key)
: undefined;

export interface LoginInfo {
id: string;
Expand Down
5 changes: 1 addition & 4 deletions src/routes/auth.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,7 @@ const validator = require("@/middlewares/validator").default;
const authHandlers = require("@/services/auth");
const authReplaceHandlers = require("@/services/auth.replace");
const mobileAuthHandlers = require("@/services/auth.mobile");

// 환경변수 SPARCSSSO_CLIENT_ID 유무에 따라 로그인 방식이 변경됩니다.
const { sparcssso: sparcsssoEnv } = require("@/loadenv");
const isAuthReplace = !sparcsssoEnv?.id;
const { isAuthReplace } = require("@/modules/auths/login");

// 로그인 페이지로 redirect합니다.
router.get(
Expand Down
21 changes: 11 additions & 10 deletions src/services/auth.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
const { sparcssso: sparcsssoEnv, nodeEnv, testAccounts } = require("@/loadenv");
const { nodeEnv, testAccounts } = require("@/loadenv");
const { userModel } = require("@/modules/stores/mongo");
const { user: userPattern } = require("@/modules/patterns").default;
const { getLoginInfo, logout, login } = require("@/modules/auths/login");
const {
ssoClient,
getLoginInfo,
logout,
login,
} = require("@/modules/auths/login");

const { unregisterDeviceToken } = require("@/modules/fcm");
const {
Expand All @@ -12,10 +17,6 @@ const {
const jwt = require("@/modules/auths/jwt");
const logger = require("@/modules/logger").default;

// SPARCS SSO
const Client = require("@/modules/auths/sparcssso");
const client = new Client(sparcsssoEnv?.id, sparcsssoEnv?.key);

const transUserData = (userData) => {
const kaistInfo = userData.kaist_info ? JSON.parse(userData.kaist_info) : {};

Expand Down Expand Up @@ -137,7 +138,7 @@ const tryLogin = async (req, res, userData, redirectOrigin, redirectPath) => {
const sparcsssoHandler = (req, res) => {
const redirectPath = decodeURIComponent(req.query?.redirect || "%2F");
const isApp = !!req.query.isApp;
const { url, state } = client.getLoginParams();
const { url, state } = ssoClient.getLoginParams();

req.session.loginAfterState = {
state: state,
Expand Down Expand Up @@ -167,7 +168,7 @@ const sparcsssoCallbackHandler = (req, res) => {
return res.redirect(redirectUrl);
}

client.getUserInfo(code).then((userDataBefore) => {
ssoClient.getUserInfo(code).then((userDataBefore) => {
const userData = transUserData(userDataBefore);
const isTestAccount = testAccounts?.includes(userData.email);
if (userData.isEligible || nodeEnv !== "production" || isTestAccount) {
Expand All @@ -176,7 +177,7 @@ const sparcsssoCallbackHandler = (req, res) => {
// 카이스트 구성원이 아닌 경우, SSO 로그아웃 이후, 로그인 실패 URI 로 이동합니다
const { sid } = userData;
const redirectUrl = new URL("/login/fail", redirectOrigin).href;
const ssoLogoutUrl = client.getLogoutUrl(sid, redirectUrl);
const ssoLogoutUrl = ssoClient.getLogoutUrl(sid, redirectUrl);
res.redirect(ssoLogoutUrl);
}
});
Expand All @@ -202,7 +203,7 @@ const logoutHandler = async (req, res) => {

// 로그아웃 URL을 생성 및 반환
const redirectUrl = new URL(redirectPath, req.origin).href;
const ssoLogoutUrl = client.getLogoutUrl(sid, redirectUrl);
const ssoLogoutUrl = ssoClient.getLogoutUrl(sid, redirectUrl);
logout(req, res);
res.json({ ssoLogoutUrl });
} catch (e) {
Expand Down
14 changes: 12 additions & 2 deletions src/services/users.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type { RequestHandler } from "express";
import { ssoClient, getLoginInfo, logout } from "@/modules/auths/login";
import { unregisterAllDeviceTokens } from "@/modules/fcm";
import logger from "@/modules/logger";
import {
Expand Down Expand Up @@ -257,6 +258,11 @@ export const getBanRecordHandler: RequestHandler = async (req, res) => {

export const withdrawHandler: RequestHandler = async (req, res) => {
try {
const redirectPath = decodeURIComponent(
(req.query.redirect as string | undefined) || "%2F"
); // TODO: Typing or Validation
const { sid } = getLoginInfo(req);

const user = await userModel.findOne({ _id: req.userOid, withdraw: false });
if (!user) {
return res.status(500).send("Users/withdraw : internal server error");
Expand All @@ -275,10 +281,14 @@ export const withdrawHandler: RequestHandler = async (req, res) => {
// 회원 탈퇴 처리 (Soft Delete)
user.withdraw = true;
user.withdrewAt = new Date(req.timestamp!);

await user.save();

res.status(200).send("Users/withdraw : withdraw successful");
// 로그아웃 처리
const redirectUrl = new URL(redirectPath, req.origin).href;
const ssoLogoutUrl =
ssoClient?.getLogoutUrl(sid, redirectUrl) ?? redirectUrl;
logout(req);
res.json({ ssoLogoutUrl });
} catch (err) {
res.status(500).send("Users/withdraw : internal server error");
}
Expand Down

0 comments on commit 4d63ff8

Please sign in to comment.