chatwoot admin panel fixes
All checks were successful
Deploy to VPS / deploy (push) Successful in 1m16s
All checks were successful
Deploy to VPS / deploy (push) Successful in 1m16s
This commit is contained in:
@@ -104,13 +104,13 @@ public class AdminSecurityConfig {
|
|||||||
.sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
|
.sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
|
||||||
.authorizeHttpRequests(auth -> auth
|
.authorizeHttpRequests(auth -> auth
|
||||||
.requestMatchers("/api/admin/login", "/api/admin/chatwoot-session").permitAll()
|
.requestMatchers("/api/admin/login", "/api/admin/chatwoot-session").permitAll()
|
||||||
.requestMatchers("/api/admin/users/**").hasAnyRole("ADMIN", "GAME_ADMIN", "TICKETS_SUPPORT")
|
.requestMatchers("/api/admin/users/**").hasAnyRole("ADMIN", "SUPPORT")
|
||||||
.requestMatchers("/api/admin/payments/**").hasAnyRole("ADMIN", "GAME_ADMIN")
|
.requestMatchers("/api/admin/payments/**").hasAnyRole("ADMIN", "SUPPORT")
|
||||||
.requestMatchers("/api/admin/payouts/**").hasAnyRole("ADMIN", "PAYOUT_SUPPORT", "GAME_ADMIN")
|
.requestMatchers("/api/admin/payouts/**").hasAnyRole("ADMIN", "SUPPORT")
|
||||||
.requestMatchers("/api/admin/rooms/**").hasAnyRole("ADMIN", "GAME_ADMIN")
|
.requestMatchers("/api/admin/rooms/**").hasAnyRole("ADMIN")
|
||||||
.requestMatchers("/api/admin/configurations/**").hasAnyRole("ADMIN", "GAME_ADMIN")
|
.requestMatchers("/api/admin/configurations/**").hasAnyRole("ADMIN")
|
||||||
.requestMatchers("/api/admin/tickets/**").hasAnyRole("ADMIN", "TICKETS_SUPPORT", "GAME_ADMIN")
|
.requestMatchers("/api/admin/tickets/**").hasAnyRole("ADMIN")
|
||||||
.requestMatchers("/api/admin/quick-answers/**").hasAnyRole("ADMIN", "TICKETS_SUPPORT", "GAME_ADMIN")
|
.requestMatchers("/api/admin/quick-answers/**").hasAnyRole("ADMIN")
|
||||||
.requestMatchers("/api/admin/**").hasRole("ADMIN")
|
.requestMatchers("/api/admin/**").hasRole("ADMIN")
|
||||||
.anyRequest().denyAll()
|
.anyRequest().denyAll()
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ public class AdminLoginController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Exchanges a Chatwoot integration API key for an admin JWT with ROLE_TICKETS_SUPPORT.
|
* Exchanges a Chatwoot integration API key for an admin JWT with ROLE_SUPPORT.
|
||||||
* Used when the admin panel is embedded in Chatwoot as a Dashboard App iframe.
|
* Used when the admin panel is embedded in Chatwoot as a Dashboard App iframe.
|
||||||
* API key must match CHATWOOT_INTEGRATION_SECRET on the server.
|
* API key must match CHATWOOT_INTEGRATION_SECRET on the server.
|
||||||
*/
|
*/
|
||||||
@@ -73,11 +73,11 @@ public class AdminLoginController {
|
|||||||
if (!chatwootIntegrationSecret.equals(request.getApiKey().trim())) {
|
if (!chatwootIntegrationSecret.equals(request.getApiKey().trim())) {
|
||||||
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("Invalid apiKey");
|
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("Invalid apiKey");
|
||||||
}
|
}
|
||||||
String token = jwtUtil.generateTokenWithRole("__chatwoot__", "ROLE_TICKETS_SUPPORT");
|
String token = jwtUtil.generateTokenWithRole("__chatwoot__", "ROLE_SUPPORT");
|
||||||
return ResponseEntity.ok(new AdminLoginResponse(
|
return ResponseEntity.ok(new AdminLoginResponse(
|
||||||
token,
|
token,
|
||||||
"__chatwoot__",
|
"__chatwoot__",
|
||||||
"ROLE_TICKETS_SUPPORT"
|
"ROLE_SUPPORT"
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,8 +7,6 @@ import com.honey.honey.repository.PaymentRepository;
|
|||||||
import com.honey.honey.repository.UserARepository;
|
import com.honey.honey.repository.UserARepository;
|
||||||
import com.honey.honey.repository.UserDRepository;
|
import com.honey.honey.repository.UserDRepository;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.springframework.security.core.Authentication;
|
|
||||||
import org.springframework.security.core.context.SecurityContextHolder;
|
|
||||||
import org.springframework.data.domain.Page;
|
import org.springframework.data.domain.Page;
|
||||||
import org.springframework.data.domain.PageRequest;
|
import org.springframework.data.domain.PageRequest;
|
||||||
import org.springframework.data.domain.Pageable;
|
import org.springframework.data.domain.Pageable;
|
||||||
@@ -16,6 +14,8 @@ import org.springframework.data.domain.Sort;
|
|||||||
import org.springframework.data.jpa.domain.Specification;
|
import org.springframework.data.jpa.domain.Specification;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.security.access.prepost.PreAuthorize;
|
import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
|
import org.springframework.security.core.Authentication;
|
||||||
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestParam;
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
@@ -31,18 +31,18 @@ import java.util.stream.Collectors;
|
|||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/api/admin/payments")
|
@RequestMapping("/api/admin/payments")
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
@PreAuthorize("hasAnyRole('ADMIN', 'GAME_ADMIN')")
|
@PreAuthorize("hasAnyRole('ADMIN', 'SUPPORT')")
|
||||||
public class AdminPaymentController {
|
public class AdminPaymentController {
|
||||||
|
|
||||||
private final PaymentRepository paymentRepository;
|
private final PaymentRepository paymentRepository;
|
||||||
private final UserARepository userARepository;
|
private final UserARepository userARepository;
|
||||||
private final UserDRepository userDRepository;
|
private final UserDRepository userDRepository;
|
||||||
|
|
||||||
private boolean isGameAdmin() {
|
private static boolean isSupport() {
|
||||||
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
|
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
|
||||||
if (auth == null || auth.getAuthorities() == null) return false;
|
if (auth == null || auth.getAuthorities() == null) return false;
|
||||||
return auth.getAuthorities().stream()
|
return auth.getAuthorities().stream()
|
||||||
.anyMatch(a -> "ROLE_GAME_ADMIN".equals(a.getAuthority()));
|
.anyMatch(a -> "ROLE_SUPPORT".equals(a.getAuthority()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping
|
@GetMapping
|
||||||
@@ -70,7 +70,7 @@ public class AdminPaymentController {
|
|||||||
|
|
||||||
Pageable pageable = PageRequest.of(page, size, sort);
|
Pageable pageable = PageRequest.of(page, size, sort);
|
||||||
|
|
||||||
List<Integer> masterIds = isGameAdmin() ? userDRepository.findMasterUserIds() : List.of();
|
List<Integer> masterIds = isSupport() ? userDRepository.findMasterUserIds() : List.of();
|
||||||
|
|
||||||
// Build specification
|
// Build specification
|
||||||
Specification<Payment> spec = (root, query, cb) -> {
|
Specification<Payment> spec = (root, query, cb) -> {
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ import java.util.stream.Collectors;
|
|||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/api/admin/payouts")
|
@RequestMapping("/api/admin/payouts")
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
@PreAuthorize("hasAnyRole('ADMIN', 'PAYOUT_SUPPORT', 'GAME_ADMIN')")
|
@PreAuthorize("hasAnyRole('ADMIN', 'SUPPORT')")
|
||||||
public class AdminPayoutController {
|
public class AdminPayoutController {
|
||||||
|
|
||||||
private final PayoutRepository payoutRepository;
|
private final PayoutRepository payoutRepository;
|
||||||
@@ -45,11 +45,11 @@ public class AdminPayoutController {
|
|||||||
private final PayoutService payoutService;
|
private final PayoutService payoutService;
|
||||||
private final LocalizationService localizationService;
|
private final LocalizationService localizationService;
|
||||||
|
|
||||||
private boolean isGameAdmin() {
|
private static boolean isSupport() {
|
||||||
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
|
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
|
||||||
if (auth == null || auth.getAuthorities() == null) return false;
|
if (auth == null || auth.getAuthorities() == null) return false;
|
||||||
return auth.getAuthorities().stream()
|
return auth.getAuthorities().stream()
|
||||||
.anyMatch(a -> "ROLE_GAME_ADMIN".equals(a.getAuthority()));
|
.anyMatch(a -> "ROLE_SUPPORT".equals(a.getAuthority()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping
|
@GetMapping
|
||||||
@@ -74,7 +74,7 @@ public class AdminPayoutController {
|
|||||||
|
|
||||||
Pageable pageable = PageRequest.of(page, size, sort);
|
Pageable pageable = PageRequest.of(page, size, sort);
|
||||||
|
|
||||||
List<Integer> masterIds = isGameAdmin() ? userDRepository.findMasterUserIds() : List.of();
|
List<Integer> masterIds = isSupport() ? userDRepository.findMasterUserIds() : List.of();
|
||||||
|
|
||||||
// Build specification
|
// Build specification
|
||||||
Specification<Payout> spec = (root, query, cb) -> {
|
Specification<Payout> spec = (root, query, cb) -> {
|
||||||
@@ -156,7 +156,7 @@ public class AdminPayoutController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping("/{id}/complete")
|
@PostMapping("/{id}/complete")
|
||||||
@PreAuthorize("hasAnyRole('ADMIN', 'PAYOUT_SUPPORT')")
|
@PreAuthorize("hasRole('ADMIN')")
|
||||||
public ResponseEntity<?> completePayout(@PathVariable Long id) {
|
public ResponseEntity<?> completePayout(@PathVariable Long id) {
|
||||||
try {
|
try {
|
||||||
Optional<Payout> payoutOpt = payoutRepository.findById(id);
|
Optional<Payout> payoutOpt = payoutRepository.findById(id);
|
||||||
@@ -179,7 +179,7 @@ public class AdminPayoutController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping("/{id}/cancel")
|
@PostMapping("/{id}/cancel")
|
||||||
@PreAuthorize("hasAnyRole('ADMIN', 'PAYOUT_SUPPORT')")
|
@PreAuthorize("hasRole('ADMIN')")
|
||||||
public ResponseEntity<?> cancelPayout(@PathVariable Long id) {
|
public ResponseEntity<?> cancelPayout(@PathVariable Long id) {
|
||||||
try {
|
try {
|
||||||
Optional<Payout> payoutOpt = payoutRepository.findById(id);
|
Optional<Payout> payoutOpt = payoutRepository.findById(id);
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ import java.util.stream.Collectors;
|
|||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/api/admin/tickets")
|
@RequestMapping("/api/admin/tickets")
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
@PreAuthorize("hasAnyRole('ADMIN', 'TICKETS_SUPPORT', 'GAME_ADMIN')")
|
@PreAuthorize("hasAnyRole('ADMIN')")
|
||||||
public class AdminSupportTicketController {
|
public class AdminSupportTicketController {
|
||||||
|
|
||||||
private final SupportTicketRepository supportTicketRepository;
|
private final SupportTicketRepository supportTicketRepository;
|
||||||
|
|||||||
@@ -25,6 +25,13 @@ import java.util.Set;
|
|||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class AdminUserController {
|
public class AdminUserController {
|
||||||
|
|
||||||
|
private static boolean isSupport() {
|
||||||
|
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
|
||||||
|
if (auth == null || auth.getAuthorities() == null) return false;
|
||||||
|
return auth.getAuthorities().stream()
|
||||||
|
.anyMatch(a -> "ROLE_SUPPORT".equals(a.getAuthority()));
|
||||||
|
}
|
||||||
|
|
||||||
/** Sortable fields: UserA properties plus UserB/UserD (handled via custom query in service). */
|
/** Sortable fields: UserA properties plus UserB/UserD (handled via custom query in service). */
|
||||||
private static final Set<String> SORTABLE_FIELDS = Set.of(
|
private static final Set<String> SORTABLE_FIELDS = Set.of(
|
||||||
"id", "screenName", "telegramId", "telegramName", "isPremium",
|
"id", "screenName", "telegramId", "telegramName", "isPremium",
|
||||||
@@ -37,15 +44,8 @@ public class AdminUserController {
|
|||||||
private final AdminUserService adminUserService;
|
private final AdminUserService adminUserService;
|
||||||
private final UserService userService;
|
private final UserService userService;
|
||||||
|
|
||||||
private boolean isGameAdmin() {
|
|
||||||
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
|
|
||||||
if (auth == null || auth.getAuthorities() == null) return false;
|
|
||||||
return auth.getAuthorities().stream()
|
|
||||||
.anyMatch(a -> "ROLE_GAME_ADMIN".equals(a.getAuthority()));
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping
|
@GetMapping
|
||||||
@PreAuthorize("hasAnyRole('ADMIN', 'GAME_ADMIN')")
|
@PreAuthorize("hasAnyRole('ADMIN', 'SUPPORT')")
|
||||||
public ResponseEntity<Map<String, Object>> getUsers(
|
public ResponseEntity<Map<String, Object>> getUsers(
|
||||||
@RequestParam(defaultValue = "0") int page,
|
@RequestParam(defaultValue = "0") int page,
|
||||||
@RequestParam(defaultValue = "50") int size,
|
@RequestParam(defaultValue = "50") int size,
|
||||||
@@ -85,7 +85,7 @@ public class AdminUserController {
|
|||||||
Long balanceMinBigint = balanceMin != null ? balanceMin * 1000000L : null;
|
Long balanceMinBigint = balanceMin != null ? balanceMin * 1000000L : null;
|
||||||
Long balanceMaxBigint = balanceMax != null ? balanceMax * 1000000L : null;
|
Long balanceMaxBigint = balanceMax != null ? balanceMax * 1000000L : null;
|
||||||
|
|
||||||
boolean excludeMasters = isGameAdmin();
|
boolean excludeMasters = isSupport();
|
||||||
Page<AdminUserDto> dtoPage = adminUserService.getUsers(
|
Page<AdminUserDto> dtoPage = adminUserService.getUsers(
|
||||||
pageable,
|
pageable,
|
||||||
search,
|
search,
|
||||||
@@ -124,7 +124,7 @@ public class AdminUserController {
|
|||||||
* Chatwoot (Telegram channel) often uses Telegram user ID as contact identifier.
|
* Chatwoot (Telegram channel) often uses Telegram user ID as contact identifier.
|
||||||
*/
|
*/
|
||||||
@GetMapping("/by-telegram-id")
|
@GetMapping("/by-telegram-id")
|
||||||
@PreAuthorize("hasAnyRole('ADMIN', 'GAME_ADMIN', 'TICKETS_SUPPORT')")
|
@PreAuthorize("hasAnyRole('ADMIN', 'SUPPORT')")
|
||||||
public ResponseEntity<Map<String, Integer>> getUserByTelegramId(@RequestParam("telegram_id") Long telegramId) {
|
public ResponseEntity<Map<String, Integer>> getUserByTelegramId(@RequestParam("telegram_id") Long telegramId) {
|
||||||
if (telegramId == null) {
|
if (telegramId == null) {
|
||||||
return ResponseEntity.badRequest().build();
|
return ResponseEntity.badRequest().build();
|
||||||
@@ -135,9 +135,9 @@ public class AdminUserController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/{id}")
|
@GetMapping("/{id}")
|
||||||
@PreAuthorize("hasAnyRole('ADMIN', 'GAME_ADMIN', 'TICKETS_SUPPORT')")
|
@PreAuthorize("hasAnyRole('ADMIN', 'SUPPORT')")
|
||||||
public ResponseEntity<AdminUserDetailDto> getUserDetail(@PathVariable Integer id) {
|
public ResponseEntity<AdminUserDetailDto> getUserDetail(@PathVariable Integer id) {
|
||||||
AdminUserDetailDto userDetail = adminUserService.getUserDetail(id, isGameAdmin());
|
AdminUserDetailDto userDetail = adminUserService.getUserDetail(id, isSupport());
|
||||||
if (userDetail == null) {
|
if (userDetail == null) {
|
||||||
return ResponseEntity.notFound().build();
|
return ResponseEntity.notFound().build();
|
||||||
}
|
}
|
||||||
@@ -145,7 +145,7 @@ public class AdminUserController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/{id}/transactions")
|
@GetMapping("/{id}/transactions")
|
||||||
@PreAuthorize("hasAnyRole('ADMIN', 'GAME_ADMIN')")
|
@PreAuthorize("hasAnyRole('ADMIN', 'SUPPORT')")
|
||||||
public ResponseEntity<Map<String, Object>> getUserTransactions(
|
public ResponseEntity<Map<String, Object>> getUserTransactions(
|
||||||
@PathVariable Integer id,
|
@PathVariable Integer id,
|
||||||
@RequestParam(defaultValue = "0") int page,
|
@RequestParam(defaultValue = "0") int page,
|
||||||
@@ -167,7 +167,7 @@ public class AdminUserController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/{id}/payments")
|
@GetMapping("/{id}/payments")
|
||||||
@PreAuthorize("hasAnyRole('ADMIN', 'GAME_ADMIN')")
|
@PreAuthorize("hasAnyRole('ADMIN', 'SUPPORT')")
|
||||||
public ResponseEntity<Map<String, Object>> getUserPayments(
|
public ResponseEntity<Map<String, Object>> getUserPayments(
|
||||||
@PathVariable Integer id,
|
@PathVariable Integer id,
|
||||||
@RequestParam(defaultValue = "0") int page,
|
@RequestParam(defaultValue = "0") int page,
|
||||||
@@ -190,7 +190,7 @@ public class AdminUserController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/{id}/payouts")
|
@GetMapping("/{id}/payouts")
|
||||||
@PreAuthorize("hasAnyRole('ADMIN', 'GAME_ADMIN')")
|
@PreAuthorize("hasAnyRole('ADMIN', 'SUPPORT')")
|
||||||
public ResponseEntity<Map<String, Object>> getUserPayouts(
|
public ResponseEntity<Map<String, Object>> getUserPayouts(
|
||||||
@PathVariable Integer id,
|
@PathVariable Integer id,
|
||||||
@RequestParam(defaultValue = "0") int page,
|
@RequestParam(defaultValue = "0") int page,
|
||||||
@@ -213,14 +213,14 @@ public class AdminUserController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/{id}/tasks")
|
@GetMapping("/{id}/tasks")
|
||||||
@PreAuthorize("hasAnyRole('ADMIN', 'GAME_ADMIN')")
|
@PreAuthorize("hasAnyRole('ADMIN', 'SUPPORT')")
|
||||||
public ResponseEntity<Map<String, Object>> getUserTasks(@PathVariable Integer id) {
|
public ResponseEntity<Map<String, Object>> getUserTasks(@PathVariable Integer id) {
|
||||||
Map<String, Object> tasks = adminUserService.getUserTasks(id);
|
Map<String, Object> tasks = adminUserService.getUserTasks(id);
|
||||||
return ResponseEntity.ok(tasks);
|
return ResponseEntity.ok(tasks);
|
||||||
}
|
}
|
||||||
|
|
||||||
@PatchMapping("/{id}/ban")
|
@PatchMapping("/{id}/ban")
|
||||||
@PreAuthorize("hasRole('ADMIN')")
|
@PreAuthorize("hasAnyRole('ADMIN', 'SUPPORT')")
|
||||||
public ResponseEntity<?> setUserBanned(
|
public ResponseEntity<?> setUserBanned(
|
||||||
@PathVariable Integer id,
|
@PathVariable Integer id,
|
||||||
@RequestBody Map<String, Boolean> body) {
|
@RequestBody Map<String, Boolean> body) {
|
||||||
@@ -237,7 +237,7 @@ public class AdminUserController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@PatchMapping("/{id}/withdrawals-enabled")
|
@PatchMapping("/{id}/withdrawals-enabled")
|
||||||
@PreAuthorize("hasAnyRole('ADMIN', 'GAME_ADMIN')")
|
@PreAuthorize("hasAnyRole('ADMIN', 'SUPPORT')")
|
||||||
public ResponseEntity<?> setWithdrawalsEnabled(
|
public ResponseEntity<?> setWithdrawalsEnabled(
|
||||||
@PathVariable Integer id,
|
@PathVariable Integer id,
|
||||||
@RequestBody Map<String, Boolean> body) {
|
@RequestBody Map<String, Boolean> body) {
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ import java.util.stream.Collectors;
|
|||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/api/admin/quick-answers")
|
@RequestMapping("/api/admin/quick-answers")
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
@PreAuthorize("hasAnyRole('ADMIN', 'TICKETS_SUPPORT', 'GAME_ADMIN')")
|
@PreAuthorize("hasAnyRole('ADMIN')")
|
||||||
public class QuickAnswerController {
|
public class QuickAnswerController {
|
||||||
|
|
||||||
private final QuickAnswerRepository quickAnswerRepository;
|
private final QuickAnswerRepository quickAnswerRepository;
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ public interface UserDRepository extends JpaRepository<UserD, Integer> {
|
|||||||
List<UserD> findAllMasters();
|
List<UserD> findAllMasters();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* IDs of users who are Masters (id = master_id and master_id > 0). Used to exclude them from GAME_ADMIN views.
|
* IDs of users who are Masters (id = master_id and master_id > 0).
|
||||||
*/
|
*/
|
||||||
@Query("SELECT d.id FROM UserD d WHERE d.id = d.masterId AND d.masterId > 0")
|
@Query("SELECT d.id FROM UserD d WHERE d.id = d.masterId AND d.masterId > 0")
|
||||||
List<Integer> findMasterUserIds();
|
List<Integer> findMasterUserIds();
|
||||||
|
|||||||
Reference in New Issue
Block a user