1- import { Injectable } from "@nestjs/common" ;
1+ import {
2+ ForbiddenException ,
3+ Injectable ,
4+ InternalServerErrorException ,
5+ } from "@nestjs/common" ;
26import { LoginRequestDto , LoginResponseDto } from "@src/user/dto/login.dto" ;
37import { BaseResultDto } from "@src/global/dto/base-result.dto" ;
48import { SetDeviceInfoRequestDto } from "@src/user/dto/set-fcm.dto" ;
@@ -21,6 +25,8 @@ import { UserEntity } from "@src/database/entity/user.entity";
2125import { UpdateConsentDto } from "@src/user/dto/update-consent.dto" ;
2226import { UserConsentRepository } from "@src/database/repository/user-consent.repository" ;
2327import { UserConsentEntity } from "@src/database/entity/user-consent.entity" ;
28+ import { LogoutRequestDto } from "@src/user/dto/logout.dto" ;
29+ import { RefreshTokenRepository } from "@src/database/repository/refresh-token.repository" ;
2430
2531@Injectable ( )
2632export class UserService {
@@ -32,6 +38,7 @@ export class UserService {
3238 private readonly deviceRepository : DeviceRepository ,
3339 private readonly userAlarmSettingRepository : UserAlarmSettingRepository ,
3440 private readonly userConsentRepository : UserConsentRepository ,
41+ private readonly refreshTokenRepository : RefreshTokenRepository ,
3542 ) { }
3643
3744 async login (
@@ -105,27 +112,20 @@ export class UserService {
105112 userCtx . userId ,
106113 ) ;
107114 if ( ! device ) {
108- throw new Error ( "Device not found" ) ; // TODO
115+ throw new ForbiddenException ( "Device not found" ) ;
109116 }
110117
111- let updated = false ;
112-
113118 if ( ! ! fcmToken ) {
114119 device . fcmToken = fcmToken ;
115- updated = true ;
116120 }
117121 if ( ! ! os ) {
118122 device . os = os ;
119- updated = true ;
120123 }
121124 if ( ! ! version ) {
122125 device . version = version ;
123- updated = true ;
124126 }
125127
126- if ( ! updated ) {
127- return BaseResultDto . OK ; // 변경된 정보가 없으면 바로 반환
128- }
128+ device . loggedIn = true ;
129129
130130 await this . dbService . db . transaction ( async ( tx : TxType ) => {
131131 await this . deviceRepository . update ( device , tx ) ;
@@ -263,6 +263,32 @@ export class UserService {
263263 return BaseResultDto . OK ;
264264 }
265265
266+ async logout (
267+ req : LogoutRequestDto ,
268+ userCtx : UserContext ,
269+ ) : Promise < BaseResultDto > {
270+ const device = await this . deviceRepository . findByPkAndUserFk (
271+ userCtx . devicePk ,
272+ userCtx . userId ,
273+ ) ;
274+
275+ if ( ! device ) {
276+ return BaseResultDto . OK ;
277+ }
278+
279+ device . loggedIn = false ;
280+
281+ await this . dbService . db . transaction ( async ( tx : TxType ) => {
282+ await this . refreshTokenRepository . deleteByOpaqueHash (
283+ req . refresh_token ,
284+ tx ,
285+ ) ;
286+ await this . deviceRepository . update ( device , tx ) ;
287+ } ) ;
288+
289+ return BaseResultDto . OK ;
290+ }
291+
266292 private async createNewUser (
267293 sub : string ,
268294 name : string ,
@@ -280,7 +306,7 @@ export class UserService {
280306 ) ;
281307
282308 if ( ! user ) {
283- throw new Error ( "Failed to create new user" ) ; // TODO
309+ throw new InternalServerErrorException ( "Failed to create new user" ) ;
284310 }
285311
286312 return user ;
@@ -297,8 +323,9 @@ export class UserService {
297323 userFk : user . pk ,
298324 fcmToken : "" , // 초기값은 빈 문자열로 설정
299325 deviceId : deviceId ,
300- os : "iOS" , // OS 정보는 추후에 업데이트 필요
301- version : "0.0.1" , // 초기 버전 정보
326+ os : "" , // OS 정보는 추후에 업데이트 필요
327+ version : "" , // 초기 버전 정보
328+ loggedIn : false ,
302329 } ,
303330 tx ,
304331 ) ;
0 commit comments