diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/member/MemberController.kt b/src/main/kotlin/kr/co/vividnext/sodalive/member/MemberController.kt index 6d12515..850f27e 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/member/MemberController.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/member/MemberController.kt @@ -40,6 +40,15 @@ class MemberController(private val service: MemberService) { ApiResponse.ok(service.logout(token.removePrefix("Bearer "), member.id!!)) } + @PostMapping("/logout/all") + fun logoutAll( + @AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member? + ) = run { + if (member == null) throw SodaException("로그인 정보를 확인해주세요.") + + ApiResponse.ok(service.logoutAll(member.id!!)) + } + @GetMapping("/info") fun getMemberInfo( @RequestParam container: String?, diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/member/MemberService.kt b/src/main/kotlin/kr/co/vividnext/sodalive/member/MemberService.kt index 1b59996..b4f11eb 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/member/MemberService.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/member/MemberService.kt @@ -376,6 +376,17 @@ class MemberService( } } + @Transactional + fun logoutAll(memberId: Long) { + val member = repository.findByIdOrNull(memberId) + ?: throw SodaException("로그인 정보를 확인해주세요.") + + member.pushToken = null + + val lock = getOrCreateLock(memberId = memberId) + lock.write { tokenRepository.deleteById(memberId) } + } + private fun getOrCreateLock(memberId: Long): ReentrantReadWriteLock { return tokenLocks.computeIfAbsent(memberId) { ReentrantReadWriteLock() } }