From 7317866f987a220a1cf4f58a98b981b3fe9bcd2f Mon Sep 17 00:00:00 2001 From: zyh Date: Mon, 25 Aug 2025 21:26:16 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=9E=E7=8E=B0JWT=E8=BA=AB=E4=BB=BD?= =?UTF-8?q?=E8=AE=A4=E8=AF=81=E6=9C=BA=E5=88=B6=EF=BC=8C=E6=96=B0=E5=A2=9E?= =?UTF-8?q?JWT=E8=AE=A4=E8=AF=81=E8=BF=87=E6=BB=A4=E5=99=A8=E5=92=8C?= =?UTF-8?q?=E6=9C=8D=E5=8A=A1=EF=BC=8C=E6=9B=B4=E6=96=B0=E9=93=BE=E6=8E=A5?= =?UTF-8?q?=E7=94=9F=E6=88=90=E6=8E=A5=E5=8F=A3=E4=BB=A5=E6=94=AF=E6=8C=81?= =?UTF-8?q?JWT=E9=AA=8C=E8=AF=81=EF=BC=8C=E5=88=A0=E9=99=A4=E6=97=A7?= =?UTF-8?q?=E7=9A=84=E7=94=A8=E6=88=B7=E6=8E=A7=E5=88=B6=E5=99=A8=EF=BC=8C?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0JWT=E8=AE=A4=E8=AF=81=E6=96=87=E6=A1=A3?= =?UTF-8?q?=EF=BC=8C=E5=A2=9E=E5=BC=BA=E9=94=99=E8=AF=AF=E5=A4=84=E7=90=86?= =?UTF-8?q?=E5=92=8C=E6=97=A5=E5=BF=97=E8=AE=B0=E5=BD=95=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/JWT认证使用说明.md | 160 ++++++++++++++++++ .../server/controller/UserController.java | 92 ---------- .../controller/link/LinkController.java | 110 +++++++++--- .../exception/GlobalExceptionHandler.java | 53 +++++- .../model/dto/link/LinkGenerateRequest.java | 4 - .../security/JwtAuthenticationFilter.java | 123 ++++++++++++++ .../server/security/JwtService.java | 43 ++++- .../server/security/SecurityConfig.java | 74 +++++++- .../service/link/LinkGenerationService.java | 31 ++-- .../GamePlatformServerApplication.class | Bin 0 -> 887 bytes .../server/config/CorsConfig.class | Bin 0 -> 1614 bytes .../server/config/SwaggerConfig.class | Bin 0 -> 2207 bytes .../controller/admin/AccountController.class | Bin 0 -> 5978 bytes .../controller/auth/AuthController$1.class | Bin 0 -> 1439 bytes .../controller/auth/AuthController.class | Bin 0 -> 4903 bytes .../controller/link/LinkController.class | Bin 4749 -> 8224 bytes .../controller/link/QrProxyController.class | Bin 4063 -> 4070 bytes .../exception/GlobalExceptionHandler$1.class | Bin 0 -> 1312 bytes .../exception/GlobalExceptionHandler$2.class | Bin 0 -> 1439 bytes .../exception/GlobalExceptionHandler.class | Bin 0 -> 9858 bytes .../mapper/account/UserAccountMapper.class | Bin 0 -> 1564 bytes .../mapper/admin/AnnouncementMapper.class | Bin 0 -> 1255 bytes .../mapper/admin/OperationLogMapper.class | Bin 0 -> 1515 bytes .../mapper/agent/AgentPointsTxMapper.class | Bin 0 -> 1263 bytes .../server/mapper/agent/LinkBatchMapper.class | Bin 0 -> 1016 bytes .../server/mapper/agent/LinkTaskMapper.class | Bin 0 -> 2213 bytes .../dto/account/AccountCreateRequest.class | Bin 0 -> 2841 bytes .../model/dto/account/AccountResponse.class | Bin 0 -> 2503 bytes .../dto/account/AccountUpdateRequest.class | Bin 0 -> 2272 bytes .../dto/account/ResetPasswordRequest.class | Bin 0 -> 1583 bytes .../server/model/dto/auth/LoginRequest.class | Bin 0 -> 984 bytes .../server/model/dto/auth/LoginResponse.class | Bin 0 -> 1745 bytes .../server/model/dto/common/PageResult.class | Bin 0 -> 1893 bytes .../model/dto/link/LinkGenerateRequest.class | Bin 1446 -> 1064 bytes .../model/dto/link/LinkGenerateResponse.class | Bin 1841 -> 1841 bytes .../model/entity/account/UserAccount.class | Bin 0 -> 2203 bytes .../model/entity/admin/Announcement.class | Bin 0 -> 2033 bytes .../model/entity/admin/OperationLog.class | Bin 0 -> 2352 bytes .../model/entity/agent/AgentPointsTx.class | Bin 0 -> 2595 bytes .../server/model/entity/agent/LinkBatch.class | Bin 0 -> 2181 bytes .../server/model/entity/agent/LinkTask.class | Bin 0 -> 3357 bytes .../security/JwtAuthenticationFilter.class | Bin 0 -> 7745 bytes .../server/security/JwtService.class | Bin 0 -> 6482 bytes .../server/security/SecurityConfig.class | Bin 0 -> 8649 bytes .../server/service/UserService.class | Bin 0 -> 7377 bytes .../service/account/AccountService.class | Bin 0 -> 11478 bytes .../server/service/auth/AuthService.class | Bin 0 -> 8906 bytes .../service/external/ScriptClient.class | Bin 6202 -> 6222 bytes ...LinkGenerationService$GenerateResult.class | Bin 3732 -> 1760 bytes .../service/link/LinkGenerationService.class | Bin 0 -> 9446 bytes .../compile/default-compile/createdFiles.lst | 18 +- .../compile/default-compile/inputFiles.lst | 2 +- .../default-testCompile/createdFiles.lst | 2 - .../default-testCompile/inputFiles.lst | 2 - 54 files changed, 551 insertions(+), 163 deletions(-) create mode 100644 docs/JWT认证使用说明.md delete mode 100644 src/main/java/com/gameplatform/server/controller/UserController.java create mode 100644 src/main/java/com/gameplatform/server/security/JwtAuthenticationFilter.java create mode 100644 target/classes/com/gameplatform/server/GamePlatformServerApplication.class create mode 100644 target/classes/com/gameplatform/server/config/CorsConfig.class create mode 100644 target/classes/com/gameplatform/server/config/SwaggerConfig.class create mode 100644 target/classes/com/gameplatform/server/controller/admin/AccountController.class create mode 100644 target/classes/com/gameplatform/server/controller/auth/AuthController$1.class create mode 100644 target/classes/com/gameplatform/server/controller/auth/AuthController.class create mode 100644 target/classes/com/gameplatform/server/exception/GlobalExceptionHandler$1.class create mode 100644 target/classes/com/gameplatform/server/exception/GlobalExceptionHandler$2.class create mode 100644 target/classes/com/gameplatform/server/exception/GlobalExceptionHandler.class create mode 100644 target/classes/com/gameplatform/server/mapper/account/UserAccountMapper.class create mode 100644 target/classes/com/gameplatform/server/mapper/admin/AnnouncementMapper.class create mode 100644 target/classes/com/gameplatform/server/mapper/admin/OperationLogMapper.class create mode 100644 target/classes/com/gameplatform/server/mapper/agent/AgentPointsTxMapper.class create mode 100644 target/classes/com/gameplatform/server/mapper/agent/LinkBatchMapper.class create mode 100644 target/classes/com/gameplatform/server/mapper/agent/LinkTaskMapper.class create mode 100644 target/classes/com/gameplatform/server/model/dto/account/AccountCreateRequest.class create mode 100644 target/classes/com/gameplatform/server/model/dto/account/AccountResponse.class create mode 100644 target/classes/com/gameplatform/server/model/dto/account/AccountUpdateRequest.class create mode 100644 target/classes/com/gameplatform/server/model/dto/account/ResetPasswordRequest.class create mode 100644 target/classes/com/gameplatform/server/model/dto/auth/LoginRequest.class create mode 100644 target/classes/com/gameplatform/server/model/dto/auth/LoginResponse.class create mode 100644 target/classes/com/gameplatform/server/model/dto/common/PageResult.class create mode 100644 target/classes/com/gameplatform/server/model/entity/account/UserAccount.class create mode 100644 target/classes/com/gameplatform/server/model/entity/admin/Announcement.class create mode 100644 target/classes/com/gameplatform/server/model/entity/admin/OperationLog.class create mode 100644 target/classes/com/gameplatform/server/model/entity/agent/AgentPointsTx.class create mode 100644 target/classes/com/gameplatform/server/model/entity/agent/LinkBatch.class create mode 100644 target/classes/com/gameplatform/server/model/entity/agent/LinkTask.class create mode 100644 target/classes/com/gameplatform/server/security/JwtAuthenticationFilter.class create mode 100644 target/classes/com/gameplatform/server/security/JwtService.class create mode 100644 target/classes/com/gameplatform/server/security/SecurityConfig.class create mode 100644 target/classes/com/gameplatform/server/service/UserService.class create mode 100644 target/classes/com/gameplatform/server/service/account/AccountService.class create mode 100644 target/classes/com/gameplatform/server/service/auth/AuthService.class create mode 100644 target/classes/com/gameplatform/server/service/link/LinkGenerationService.class delete mode 100644 target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/createdFiles.lst delete mode 100644 target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst diff --git a/docs/JWT认证使用说明.md b/docs/JWT认证使用说明.md new file mode 100644 index 0000000..74ad4b7 --- /dev/null +++ b/docs/JWT认证使用说明.md @@ -0,0 +1,160 @@ +# JWT认证使用说明 + +## 概述 + +系统已从手动传递操作者信息的头部参数改为使用JWT(JSON Web Token)进行身份认证。这种方式更加安全、标准化,并且符合REST API的最佳实践。 + +## 认证流程 + +### 1. 用户登录获取JWT令牌 + +```http +POST /api/auth/login +Content-Type: application/json + +{ + "username": "your_username", + "password": "your_password" +} +``` + +响应示例: +```json +{ + "token": "eyJhbGciOiJIUzI1NiJ9...", + "userType": "AGENT", + "userId": 123, + "username": "your_username" +} +``` + +### 2. 使用JWT令牌调用受保护的接口 + +在请求头中添加 `Authorization` 头: + +```http +POST /api/link/generate +Authorization: Bearer eyJhbGciOiJIUzI1NiJ9... +Content-Type: application/json + +{ + "times": 10, + "perTimeQuantity": 5 +} +``` + +## 链接生成接口 + +### 接口地址 +`POST /api/link/generate` + +### 请求头 +- `Authorization: Bearer {JWT_TOKEN}` - 必需,JWT认证令牌 +- `Content-Type: application/json` - 必需 + +### 请求参数 +```json +{ + "times": 10, // 本次打脚本的次数 + "perTimeQuantity": 5 // 每次打的数量 +} +``` + +### 响应示例 +```json +{ + "batchId": 456, + "deductPoints": 50, + "expireAt": "2024-01-15T16:30:00", + "codeNos": ["ABC12345", "DEF67890", ...] +} +``` + +## 权限控制 + +### 代理用户 +- 只能为自己生成链接 +- 必须检查积分余额 +- 生成链接时扣除相应积分 + +### 管理员用户 +- 只能为自己生成链接 +- 跳过积分检查 +- 不扣除积分 + +## 安全特性 + +1. **JWT令牌验证**:每个请求都会验证JWT令牌的有效性 +2. **自动过期**:JWT令牌有自动过期时间(默认30分钟) +3. **用户身份验证**:从JWT中自动提取用户ID、用户类型等信息 +4. **权限控制**:基于用户类型进行不同的业务逻辑处理 + +## 错误处理 + +### 常见错误 + +1. **缺少认证令牌** + ```json + { + "error": "用户未认证" + } + ``` + +2. **令牌无效或过期** + ```json + { + "error": "JWT token validation failed" + } + ``` + +3. **权限不足** + ```json + { + "error": "非法操作者类型" + } + ``` + +## 技术实现 + +### 核心组件 + +1. **JwtService**:JWT令牌的生成和解析 +2. **JwtAuthenticationFilter**:自动处理JWT认证的Web过滤器 +3. **SecurityConfig**:Spring Security配置,定义哪些接口需要认证 +4. **LinkController**:使用Spring Security上下文获取用户信息 + +### 认证流程 + +``` +请求 → JwtAuthenticationFilter → JWT解析 → 创建认证对象 → Spring Security上下文 → 控制器获取用户信息 +``` + +## 迁移说明 + +### 从旧版本迁移 + +如果您之前使用的是手动传递操作者信息的头部参数: + +**旧方式(已废弃):** +```http +X-Operator-Id: 123 +X-Operator-Type: AGENT +``` + +**新方式:** +```http +Authorization: Bearer eyJhbGciOiJIUzI1NiJ9... +``` + +### 兼容性 + +- 旧的头参数方式已被完全移除 +- 所有链接相关接口现在都需要JWT认证 +- 确保在调用接口前先获取有效的JWT令牌 + +## 最佳实践 + +1. **令牌管理**:客户端应妥善保存JWT令牌,并在过期前刷新 +2. **安全传输**:始终使用HTTPS传输JWT令牌 +3. **错误处理**:客户端应处理认证失败的情况,引导用户重新登录 +4. **日志记录**:系统会自动记录所有认证相关的操作日志 diff --git a/src/main/java/com/gameplatform/server/controller/UserController.java b/src/main/java/com/gameplatform/server/controller/UserController.java deleted file mode 100644 index d4f81de..0000000 --- a/src/main/java/com/gameplatform/server/controller/UserController.java +++ /dev/null @@ -1,92 +0,0 @@ -package com.gameplatform.server.controller; - -import com.gameplatform.server.model.dto.account.AccountCreateRequest; -import com.gameplatform.server.model.dto.account.AccountResponse; -import com.gameplatform.server.model.dto.account.AccountUpdateRequest; -import com.gameplatform.server.model.dto.common.PageResult; -import com.gameplatform.server.service.account.AccountService; -import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.Parameter; -import io.swagger.v3.oas.annotations.tags.Tag; -import jakarta.validation.Valid; -import org.springframework.http.HttpStatus; -import org.springframework.web.bind.annotation.*; -import reactor.core.publisher.Mono; - -/** - * 用户接口控制器 - 基于UserAccount实体 - * 提供用户账户的基本CRUD操作 - */ -@RestController -@RequestMapping("/api/users") -@Tag(name = "用户账户管理", description = "用户账户的增删改查操作") -public class UserController { - private final AccountService accountService; - - public UserController(AccountService accountService) { - this.accountService = accountService; - } - - /** - * 根据ID获取用户账户信息 - */ - @GetMapping("/{id}") - @Operation(summary = "获取用户详情", description = "根据用户ID获取用户详细信息") - public Mono getById(@Parameter(description = "用户ID") @PathVariable Long id) { - return accountService.get(id); - } - - /** - * 分页查询用户列表 - */ - @GetMapping - @Operation(summary = "获取用户列表", description = "分页获取用户列表,支持按用户类型、状态、关键词筛选") - public Mono> list( - @Parameter(description = "用户类型:ADMIN 或 AGENT") @RequestParam(value = "userType", required = false) String userType, - @Parameter(description = "账户状态:ENABLED 或 DISABLED") @RequestParam(value = "status", required = false) String status, - @Parameter(description = "搜索关键词") @RequestParam(value = "keyword", required = false) String keyword, - @Parameter(description = "页码,默认1") @RequestParam(value = "page", defaultValue = "1") Integer page, - @Parameter(description = "每页大小,默认20") @RequestParam(value = "size", defaultValue = "20") Integer size - ) { - return accountService.list(userType, status, keyword, page, size); - } - - /** - * 创建新用户账户 - */ - @PostMapping - @ResponseStatus(HttpStatus.CREATED) - @Operation(summary = "创建用户", description = "创建新的代理用户账户") - public Mono create(@Valid @RequestBody AccountCreateRequest request) { - return accountService.create(request); - } - - /** - * 更新用户账户信息 - */ - @PutMapping("/{id}") - @Operation(summary = "更新用户", description = "更新用户账户信息") - public Mono update(@Parameter(description = "用户ID") @PathVariable Long id, @Valid @RequestBody AccountUpdateRequest request) { - return accountService.update(id, request); - } - - /** - * 启用用户账户 - */ - @PostMapping("/{id}/enable") - @ResponseStatus(HttpStatus.NO_CONTENT) - @Operation(summary = "启用用户", description = "启用指定用户账户") - public Mono enable(@Parameter(description = "用户ID") @PathVariable Long id) { - return accountService.setStatus(id, "ENABLED").then(); - } - - /** - * 禁用用户账户 - */ - @PostMapping("/{id}/disable") - @ResponseStatus(HttpStatus.NO_CONTENT) - @Operation(summary = "禁用用户", description = "禁用指定用户账户") - public Mono disable(@Parameter(description = "用户ID") @PathVariable Long id) { - return accountService.setStatus(id, "DISABLED").then(); - } -} \ No newline at end of file diff --git a/src/main/java/com/gameplatform/server/controller/link/LinkController.java b/src/main/java/com/gameplatform/server/controller/link/LinkController.java index ef03747..29b1d99 100644 --- a/src/main/java/com/gameplatform/server/controller/link/LinkController.java +++ b/src/main/java/com/gameplatform/server/controller/link/LinkController.java @@ -3,18 +3,26 @@ package com.gameplatform.server.controller.link; import com.gameplatform.server.model.dto.link.LinkGenerateRequest; import com.gameplatform.server.model.dto.link.LinkGenerateResponse; import com.gameplatform.server.service.link.LinkGenerationService; +import io.jsonwebtoken.Claims; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.validation.Valid; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.ReactiveSecurityContextHolder; import org.springframework.web.bind.annotation.*; +import org.springframework.web.server.ServerWebExchange; import reactor.core.publisher.Mono; - @RestController @RequestMapping("/api/link") -@Tag(name = "链接管理", description = "生成链接与二维码代理") +@Tag(name = "链接管理", description = "链接生成和管理相关接口") public class LinkController { + private static final Logger log = LoggerFactory.getLogger(LinkController.class); + private final LinkGenerationService linkGenerationService; public LinkController(LinkGenerationService linkGenerationService) { @@ -22,27 +30,87 @@ public class LinkController { } @PostMapping("/generate") - @ResponseStatus(HttpStatus.CREATED) - @Operation(summary = "生成链接批次", description = "times * perTimeQuantity = 目标点数;代理需扣点,管理员不扣") - public Mono generate(@Valid @RequestBody LinkGenerateRequest req, - @RequestHeader(value = "X-Operator-Id", required = false) Long operatorId, - @RequestHeader(value = "X-Operator-Type", required = false) String operatorType) { - // 暂时用两个 Header 传操作者信息;后续接入 JWT 解析 - Long targetAccountId = req.getAgentAccountId() != null ? req.getAgentAccountId() : operatorId; - return linkGenerationService.generateLinks(operatorId, safeUpper(operatorType), targetAccountId, - defaultInt(req.getTimes(), 0), defaultInt(req.getPerTimeQuantity(), 0)) - .map(r -> { - LinkGenerateResponse resp = new LinkGenerateResponse(); - resp.setBatchId(r.getBatchId()); - resp.setDeductPoints(r.getNeedPoints()); - resp.setExpireAt(r.getExpireAt()); - resp.setCodeNos(r.getCodeNos()); - return resp; + @ResponseStatus(HttpStatus.OK) + @Operation(summary = "生成链接批次", description = "生成指定数量的链接批次。所有用户(管理员和代理商)都只能为自己生成链接,代理用户生成链接时会扣除积分,管理员生成链接时不扣除积分") + public Mono generateLinks(@Valid @RequestBody LinkGenerateRequest request, + Authentication authentication) { + log.info("=== 开始处理链接生成请求 ==="); + log.info("请求参数: times={}, perTimeQuantity={}", + request.getTimes(), request.getPerTimeQuantity()); + + log.info("=== 开始检查认证信息 ==="); + log.info("Authentication: {}", authentication); + + if (authentication == null) { + log.error("=== 认证失败:Authentication为空 ==="); + return Mono.error(new IllegalArgumentException("用户未认证:Authentication为空")); + } + + log.info("Authentication获取成功: {}", authentication); + log.info("Authentication是否已认证: {}", authentication.isAuthenticated()); + log.info("Authentication的principal: {}", authentication.getPrincipal()); + log.info("Authentication的authorities: {}", authentication.getAuthorities()); + log.info("Authentication的details: {}", authentication.getDetails()); + + if (!authentication.isAuthenticated()) { + log.error("=== 认证失败:Authentication未通过验证 ==="); + log.error("Authentication详情: {}", authentication); + return Mono.error(new IllegalArgumentException("用户未认证:Authentication未通过验证")); + } + + log.info("=== 认证验证通过 ==="); + + // 从认证对象中获取用户信息 + log.info("开始解析Claims信息"); + Claims claims = (Claims) authentication.getDetails(); + if (claims == null) { + log.error("=== 认证失败:Claims为空 ==="); + log.error("Authentication details: {}", authentication.getDetails()); + return Mono.error(new IllegalArgumentException("用户未认证:Claims为空")); + } + + log.info("Claims获取成功,开始解析用户信息"); + log.info("Claims内容: {}", claims); + log.info("Claims的subject: {}", claims.getSubject()); + log.info("Claims的issuedAt: {}", claims.getIssuedAt()); + log.info("Claims的expiration: {}", claims.getExpiration()); + + Long operatorId = claims.get("userId", Long.class); + String operatorType = claims.get("userType", String.class); + String username = claims.get("username", String.class); + + log.info("解析出的用户信息 - operatorId: {}, operatorType: {}, username: {}", + operatorId, operatorType, username); + + if (operatorId == null || operatorType == null) { + log.error("=== 认证失败:缺少必要的用户信息 ==="); + log.error("operatorId: {}, operatorType: {}, username: {}", operatorId, operatorType, username); + log.error("Claims中所有键: {}", claims.keySet()); + return Mono.error(new IllegalArgumentException("用户未认证:缺少必要的用户信息")); + } + + log.info("=== 用户认证信息完整,开始处理业务逻辑 ==="); + log.info("操作者信息: operatorId={}, operatorType={}, username={}", + operatorId, operatorType, username); + log.info("业务参数: times={}, perTimeQuantity={}", + request.getTimes(), request.getPerTimeQuantity()); + + return linkGenerationService.generateLinks(operatorId, operatorType, + request.getTimes(), request.getPerTimeQuantity()) + .map(result -> { + log.info("链接生成成功,batchId: {}, 扣除积分: {}, 过期时间: {}", + result.getBatchId(), result.getNeedPoints(), result.getExpireAt()); + LinkGenerateResponse response = new LinkGenerateResponse(); + response.setBatchId(result.getBatchId()); + response.setDeductPoints(result.getNeedPoints()); + response.setExpireAt(result.getExpireAt()); + response.setCodeNos(result.getCodeNos()); + return response; + }) + .doOnError(error -> { + log.error("链接生成失败: {}", error.getMessage(), error); }); } - - private static String safeUpper(String s) { return s == null ? null : s.toUpperCase(); } - private static int defaultInt(Integer v, int d) { return v == null ? d : v; } } diff --git a/src/main/java/com/gameplatform/server/exception/GlobalExceptionHandler.java b/src/main/java/com/gameplatform/server/exception/GlobalExceptionHandler.java index aa0db4a..0169e7f 100644 --- a/src/main/java/com/gameplatform/server/exception/GlobalExceptionHandler.java +++ b/src/main/java/com/gameplatform/server/exception/GlobalExceptionHandler.java @@ -6,6 +6,9 @@ import org.springframework.http.HttpStatus; import org.springframework.web.bind.support.WebExchangeBindException; import org.springframework.web.server.ResponseStatusException; import org.springframework.web.server.ServerWebInputException; +import org.springframework.security.access.AccessDeniedException; +import org.springframework.security.authentication.BadCredentialsException; +import org.springframework.security.core.AuthenticationException; import jakarta.validation.ConstraintViolation; import jakarta.validation.ConstraintViolationException; import org.springframework.web.bind.annotation.ExceptionHandler; @@ -22,21 +25,45 @@ public class GlobalExceptionHandler { @ExceptionHandler(IllegalArgumentException.class) @ResponseStatus(HttpStatus.BAD_REQUEST) public Object handleBadRequest(IllegalArgumentException e) { - log.info("400 BadRequest: {}", e.getMessage()); + log.warn("400 BadRequest: {} - Stack: {}", e.getMessage(), getStackTrace(e)); return body(HttpStatus.BAD_REQUEST.value(), e.getMessage()); } @ExceptionHandler(IllegalStateException.class) @ResponseStatus(HttpStatus.FORBIDDEN) public Object handleForbidden(IllegalStateException e) { - log.info("403 Forbidden: {}", e.getMessage()); + log.warn("403 Forbidden: {} - Stack: {}", e.getMessage(), getStackTrace(e)); return body(HttpStatus.FORBIDDEN.value(), e.getMessage()); } + // 认证相关异常处理 + @ExceptionHandler(AuthenticationException.class) + @ResponseStatus(HttpStatus.UNAUTHORIZED) + public Object handleAuthenticationException(AuthenticationException e) { + log.warn("401 Authentication Failed: {} - Type: {} - Stack: {}", + e.getMessage(), e.getClass().getSimpleName(), getStackTrace(e)); + return body(HttpStatus.UNAUTHORIZED.value(), "认证失败: " + e.getMessage()); + } + + @ExceptionHandler(BadCredentialsException.class) + @ResponseStatus(HttpStatus.UNAUTHORIZED) + public Object handleBadCredentials(BadCredentialsException e) { + log.warn("401 Bad Credentials: {} - Stack: {}", e.getMessage(), getStackTrace(e)); + return body(HttpStatus.UNAUTHORIZED.value(), "用户名或密码错误"); + } + + @ExceptionHandler(AccessDeniedException.class) + @ResponseStatus(HttpStatus.FORBIDDEN) + public Object handleAccessDenied(AccessDeniedException e) { + log.warn("403 Access Denied: {} - Stack: {}", e.getMessage(), getStackTrace(e)); + return body(HttpStatus.FORBIDDEN.value(), "访问被拒绝: " + e.getMessage()); + } + @ExceptionHandler(WebExchangeBindException.class) @ResponseStatus(HttpStatus.BAD_REQUEST) public Object handleBindException(WebExchangeBindException e) { - log.info("400 ValidationError: {}", e.getMessage()); + log.warn("400 ValidationError: {} - Field errors: {} - Global errors: {}", + e.getMessage(), e.getFieldErrors().size(), e.getGlobalErrors().size()); var details = new java.util.LinkedHashMap(); e.getFieldErrors().forEach(fe -> details.put(fe.getField(), fe.getDefaultMessage())); e.getGlobalErrors().forEach(ge -> details.put(ge.getObjectName(), ge.getDefaultMessage())); @@ -46,7 +73,8 @@ public class GlobalExceptionHandler { @ExceptionHandler(ConstraintViolationException.class) @ResponseStatus(HttpStatus.BAD_REQUEST) public Object handleConstraintViolation(ConstraintViolationException e) { - log.info("400 ConstraintViolation: {}", e.getMessage()); + log.warn("400 ConstraintViolation: {} - Violations: {}", + e.getMessage(), e.getConstraintViolations().size()); var details = new java.util.LinkedHashMap(); for (ConstraintViolation v : e.getConstraintViolations()) { details.put(String.valueOf(v.getPropertyPath()), v.getMessage()); @@ -57,21 +85,24 @@ public class GlobalExceptionHandler { @ExceptionHandler(ServerWebInputException.class) @ResponseStatus(HttpStatus.BAD_REQUEST) public Object handleInput(ServerWebInputException e) { - log.info("400 InputError: {}", e.getMessage()); + log.warn("400 InputError: {} - Reason: {} - Stack: {}", + e.getMessage(), e.getReason(), getStackTrace(e)); return body(HttpStatus.BAD_REQUEST.value(), "请求解析失败: " + e.getReason()); } @ExceptionHandler(ResponseStatusException.class) public Object handleRse(ResponseStatusException e) { var status = e.getStatusCode(); - log.info("{} ResponseStatusException: {}", status, e.getReason()); + log.warn("{} ResponseStatusException: {} - Stack: {}", + status, e.getReason(), getStackTrace(e)); return body(status.value(), e.getReason()); } @ExceptionHandler(Exception.class) @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) public Object handleOther(Exception e) { - log.error("500 InternalServerError", e); + log.error("500 InternalServerError: {} - Type: {} - Stack: {}", + e.getMessage(), e.getClass().getSimpleName(), getStackTrace(e), e); return body(HttpStatus.INTERNAL_SERVER_ERROR.value(), "服务器内部错误"); } @@ -91,4 +122,12 @@ public class GlobalExceptionHandler { put("timestamp", Instant.now().toString()); }}; } + + private String getStackTrace(Exception e) { + StackTraceElement[] stackTrace = e.getStackTrace(); + if (stackTrace.length > 0) { + return stackTrace[0].toString(); + } + return "No stack trace available"; + } } diff --git a/src/main/java/com/gameplatform/server/model/dto/link/LinkGenerateRequest.java b/src/main/java/com/gameplatform/server/model/dto/link/LinkGenerateRequest.java index b054ce0..f3dae8d 100644 --- a/src/main/java/com/gameplatform/server/model/dto/link/LinkGenerateRequest.java +++ b/src/main/java/com/gameplatform/server/model/dto/link/LinkGenerateRequest.java @@ -7,15 +7,11 @@ public class LinkGenerateRequest { private Integer times; @Schema(description = "每次打的数量", example = "5") private Integer perTimeQuantity; - @Schema(description = "为哪个代理账户生成(管理员可指定,代理可省略或为自己)") - private Long agentAccountId; public Integer getTimes() { return times; } public void setTimes(Integer times) { this.times = times; } public Integer getPerTimeQuantity() { return perTimeQuantity; } public void setPerTimeQuantity(Integer perTimeQuantity) { this.perTimeQuantity = perTimeQuantity; } - public Long getAgentAccountId() { return agentAccountId; } - public void setAgentAccountId(Long agentAccountId) { this.agentAccountId = agentAccountId; } } diff --git a/src/main/java/com/gameplatform/server/security/JwtAuthenticationFilter.java b/src/main/java/com/gameplatform/server/security/JwtAuthenticationFilter.java new file mode 100644 index 0000000..fa76b82 --- /dev/null +++ b/src/main/java/com/gameplatform/server/security/JwtAuthenticationFilter.java @@ -0,0 +1,123 @@ +package com.gameplatform.server.security; + +import io.jsonwebtoken.Claims; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.http.HttpHeaders; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.core.context.SecurityContext; +import org.springframework.security.core.context.SecurityContextImpl; +import org.springframework.security.core.context.ReactiveSecurityContextHolder; +import org.springframework.stereotype.Component; +import org.springframework.web.server.ServerWebExchange; +import org.springframework.web.server.WebFilter; +import org.springframework.web.server.WebFilterChain; +import reactor.core.publisher.Mono; + +import java.util.Collections; + +@Component +public class JwtAuthenticationFilter implements WebFilter { + private static final Logger log = LoggerFactory.getLogger(JwtAuthenticationFilter.class); + + private final JwtService jwtService; + + public JwtAuthenticationFilter(JwtService jwtService) { + this.jwtService = jwtService; + } + + @Override + public Mono filter(ServerWebExchange exchange, WebFilterChain chain) { + String path = exchange.getRequest().getPath().value(); + String method = exchange.getRequest().getMethod().name(); + + log.info("=== JWT过滤器开始处理请求 ==="); + log.info("请求路径: {}, 请求方法: {}", path, method); + + String authHeader = exchange.getRequest().getHeaders().getFirst(HttpHeaders.AUTHORIZATION); + log.info("Authorization头: {}", authHeader != null ? authHeader.substring(0, Math.min(20, authHeader.length())) + "..." : "null"); + + if (authHeader == null) { + log.info("未找到Authorization头,跳过JWT认证,继续处理请求"); + return chain.filter(exchange); + } + + if (!authHeader.startsWith("Bearer ")) { + log.warn("Authorization头格式无效,期望格式: 'Bearer ',实际: {}", authHeader); + log.info("跳过JWT认证,继续处理请求"); + return chain.filter(exchange); + } + + String token = authHeader.substring(7); + log.info("开始处理JWT token,token长度: {}", token.length()); + log.debug("JWT token内容: {}", token); + + try { + log.info("开始解析JWT token"); + Claims claims = jwtService.parse(token); + log.info("JWT token解析成功"); + + Long userId = claims.get("userId", Long.class); + String userType = claims.get("userType", String.class); + String username = claims.get("username", String.class); + String subject = claims.getSubject(); + + log.info("JWT claims解析结果:"); + log.info(" - subject: {}", subject); + log.info(" - userId: {}", userId); + log.info(" - userType: {}", userType); + log.info(" - username: {}", username); + log.info(" - issuedAt: {}", claims.getIssuedAt()); + log.info(" - expiration: {}", claims.getExpiration()); + log.info(" - 所有claims键: {}", claims.keySet()); + + if (userId == null || userType == null || username == null) { + log.warn("JWT token中缺少必要的claims信息"); + log.warn(" - userId: {}", userId); + log.warn(" - userType: {}", userType); + log.warn(" - username: {}", username); + log.info("跳过JWT认证,继续处理请求"); + return chain.filter(exchange); + } + + // 创建Spring Security的Authentication对象 + log.info("开始创建Authentication对象"); + UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken( + username, // principal + null, // credentials (不需要密码) + Collections.singletonList(new SimpleGrantedAuthority("ROLE_" + userType.toUpperCase())) + ); + + // 设置认证详情,包含JWT claims信息 + authentication.setDetails(claims); + + log.info("Authentication对象创建成功: {}", authentication); + log.info("Authentication是否已认证: {}", authentication.isAuthenticated()); + log.info("Authentication的principal: {}", authentication.getPrincipal()); + log.info("Authentication的authorities: {}", authentication.getAuthorities()); + log.info("Authentication的details: {}", authentication.getDetails()); + + // 创建安全上下文并设置认证信息 + SecurityContext securityContext = new SecurityContextImpl(authentication); + + log.info("=== JWT token验证成功,设置安全上下文 ==="); + log.info("用户: {} (ID: {}, 类型: {}) 在路径: {} 上JWT验证通过", + username, userId, userType, path); + + // 将安全上下文设置到ReactiveSecurityContextHolder中 + return chain.filter(exchange) + .contextWrite(ReactiveSecurityContextHolder.withSecurityContext(Mono.just(securityContext))); + + } catch (Exception e) { + log.error("=== JWT token验证失败 ==="); + log.error("请求路径: {}", path); + log.error("Authorization头: {}", authHeader); + log.error("错误详情: {}", e.getMessage(), e); + log.info("JWT认证失败,继续处理请求(未认证状态)"); + } + + log.info("JWT过滤器处理完成,继续处理请求"); + return chain.filter(exchange); + } +} diff --git a/src/main/java/com/gameplatform/server/security/JwtService.java b/src/main/java/com/gameplatform/server/security/JwtService.java index c84e6a3..481fb64 100644 --- a/src/main/java/com/gameplatform/server/security/JwtService.java +++ b/src/main/java/com/gameplatform/server/security/JwtService.java @@ -27,9 +27,14 @@ public class JwtService { byte[] bytes = secret.length() < 32 ? (secret + "_pad_to_32_chars_secret_key_value").getBytes() : secret.getBytes(); this.key = Keys.hmacShaKeyFor(bytes); this.accessTokenMinutes = accessTokenMinutes; + log.info("JWT服务初始化完成 - 密钥长度: {} bytes, token过期时间: {} 分钟", bytes.length, accessTokenMinutes); } public String generateToken(String subject, String userType, Long userId, String username, Map extra) { + log.info("=== 开始生成JWT token ==="); + log.info("生成参数: subject={}, userType={}, userId={}, username={}, extra={}", + subject, userType, userId, username, extra); + Instant now = Instant.now(); var builder = Jwts.builder() .setSubject(subject) @@ -41,14 +46,44 @@ public class JwtService { if (extra != null) { extra.forEach(builder::claim); } + + log.info("JWT builder配置完成,开始签名"); String token = builder.signWith(key, SignatureAlgorithm.HS256).compact(); - if (log.isDebugEnabled()) { - log.debug("JWT generated subject={}, userType={}, userId={}, username={} expInMin={}", subject, userType, userId, username, accessTokenMinutes); - } + + log.info("=== JWT token生成成功 ==="); + log.info("token长度: {} 字符", token.length()); + log.info("过期时间: {} 分钟后", accessTokenMinutes); + log.info("完整token: {}", token); + return token; } public io.jsonwebtoken.Claims parse(String token) { - return Jwts.parserBuilder().setSigningKey(key).build().parseClaimsJws(token).getBody(); + log.info("=== 开始解析JWT token ==="); + log.info("token长度: {} 字符", token.length()); + log.debug("完整token: {}", token); + + try { + log.info("开始验证JWT签名"); + io.jsonwebtoken.Claims claims = Jwts.parserBuilder() + .setSigningKey(key) + .build() + .parseClaimsJws(token) + .getBody(); + + log.info("=== JWT token解析成功 ==="); + log.info("解析结果:"); + log.info(" - subject: {}", claims.getSubject()); + log.info(" - issuedAt: {}", claims.getIssuedAt()); + log.info(" - expiration: {}", claims.getExpiration()); + log.info(" - 所有claims: {}", claims); + + return claims; + } catch (Exception e) { + log.error("=== JWT token解析失败 ==="); + log.error("token: {}", token); + log.error("错误详情: {}", e.getMessage(), e); + throw e; + } } } diff --git a/src/main/java/com/gameplatform/server/security/SecurityConfig.java b/src/main/java/com/gameplatform/server/security/SecurityConfig.java index 1800fc2..c8d745a 100644 --- a/src/main/java/com/gameplatform/server/security/SecurityConfig.java +++ b/src/main/java/com/gameplatform/server/security/SecurityConfig.java @@ -1,37 +1,107 @@ package com.gameplatform.server.security; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.HttpMethod; - +import org.springframework.security.authentication.ReactiveAuthenticationManager; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity; +import org.springframework.security.config.web.server.SecurityWebFiltersOrder; import org.springframework.security.config.web.server.ServerHttpSecurity; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.web.server.SecurityWebFilterChain; +import org.springframework.security.web.server.context.ServerSecurityContextRepository; +import org.springframework.security.web.server.context.WebSessionServerSecurityContextRepository; +import reactor.core.publisher.Mono; @Configuration @EnableWebFluxSecurity public class SecurityConfig { + private static final Logger log = LoggerFactory.getLogger(SecurityConfig.class); + + @Autowired + private JwtAuthenticationFilter jwtAuthenticationFilter; @Bean public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) { - return http + log.info("=== 开始配置Spring Security安全链 ==="); + + SecurityWebFilterChain chain = http .csrf(ServerHttpSecurity.CsrfSpec::disable) .cors(cors -> {}) .httpBasic(ServerHttpSecurity.HttpBasicSpec::disable) .formLogin(ServerHttpSecurity.FormLoginSpec::disable) + .securityContextRepository(securityContextRepository()) + .authenticationManager(authenticationManager()) .authorizeExchange(ex -> ex .pathMatchers("/actuator/**").permitAll() .pathMatchers(HttpMethod.POST, "/api/auth/login").permitAll() .pathMatchers(HttpMethod.GET, "/api/auth/me").permitAll() + .pathMatchers("/api/link/**").authenticated() // 链接接口需要认证 .anyExchange().permitAll() // 其他接口后续再收紧 ) + // 关键:将JWT过滤器集成到Security过滤链中,放在AUTHENTICATION位置 + .addFilterAt(jwtAuthenticationFilter, SecurityWebFiltersOrder.AUTHENTICATION) .build(); + + log.info("=== Spring Security安全链配置完成 ==="); + log.info("安全配置详情:"); + log.info(" - CSRF: 已禁用"); + log.info(" - CORS: 已启用"); + log.info(" - HTTP Basic: 已禁用"); + log.info(" - Form Login: 已禁用"); + log.info(" - JWT过滤器: 已集成到Security链中 (AUTHENTICATION位置)"); + log.info(" - 路径权限配置:"); + log.info(" * /actuator/** -> 允许所有"); + log.info(" * POST /api/auth/login -> 允许所有"); + log.info(" * GET /api/auth/me -> 允许所有"); + log.info(" * /api/link/** -> 需要认证"); + log.info(" * 其他路径 -> 允许所有"); + + return chain; + } + + @Bean + public ReactiveAuthenticationManager authenticationManager() { + log.info("创建JWT认证管理器"); + return authentication -> { + log.info("=== JWT认证管理器开始处理认证 ==="); + log.info("认证对象: {}", authentication); + + if (authentication instanceof UsernamePasswordAuthenticationToken) { + UsernamePasswordAuthenticationToken auth = (UsernamePasswordAuthenticationToken) authentication; + log.info("处理UsernamePasswordAuthenticationToken认证"); + log.info("Principal: {}", auth.getPrincipal()); + log.info("Credentials: {}", auth.getCredentials()); + log.info("Authorities: {}", auth.getAuthorities()); + log.info("Details: {}", auth.getDetails()); + log.info("是否已认证: {}", auth.isAuthenticated()); + + // 如果已经通过JWT过滤器认证,直接返回 + if (auth.isAuthenticated()) { + log.info("认证对象已经通过验证,返回成功"); + return Mono.just(auth); + } + } + + log.info("认证对象未通过验证,返回失败"); + return Mono.empty(); + }; + } + + @Bean + public ServerSecurityContextRepository securityContextRepository() { + log.info("创建安全上下文仓库"); + return new WebSessionServerSecurityContextRepository(); } @Bean public PasswordEncoder passwordEncoder() { + log.info("创建BCrypt密码编码器"); return new BCryptPasswordEncoder(); } } diff --git a/src/main/java/com/gameplatform/server/service/link/LinkGenerationService.java b/src/main/java/com/gameplatform/server/service/link/LinkGenerationService.java index 16751d1..e4fc2f6 100644 --- a/src/main/java/com/gameplatform/server/service/link/LinkGenerationService.java +++ b/src/main/java/com/gameplatform/server/service/link/LinkGenerationService.java @@ -46,46 +46,43 @@ public class LinkGenerationService { @Transactional public Mono generateLinks(Long operatorId, String operatorType, - Long targetAccountId, int times, int perTimeQuantity) { - return Mono.fromCallable(() -> doGenerate(operatorId, operatorType, targetAccountId, times, perTimeQuantity)) + return Mono.fromCallable(() -> doGenerate(operatorId, operatorType, times, perTimeQuantity)) .subscribeOn(Schedulers.boundedElastic()); } private GenerateResult doGenerate(Long operatorId, String operatorType, - Long targetAccountId, int times, int perTimeQuantity) { if (times <= 0 || perTimeQuantity <= 0) { throw new IllegalArgumentException("times 与 perTimeQuantity 必须为正整数"); } - UserAccount target = userAccountMapper.findById(targetAccountId); - if (target == null) { - throw new IllegalArgumentException("目标账户不存在"); + // 获取操作者账户信息 + UserAccount operator = userAccountMapper.findById(operatorId); + if (operator == null) { + throw new IllegalArgumentException("操作者账户不存在"); } + boolean isAdminOperator = "ADMIN".equalsIgnoreCase(operatorType); if (!isAdminOperator && !"AGENT".equalsIgnoreCase(operatorType)) { throw new IllegalArgumentException("非法操作者类型"); } - if (!"AGENT".equalsIgnoreCase(target.getUserType())) { - throw new IllegalArgumentException("仅支持为代理账户生成链接"); - } long needPoints = (long) times * (long) perTimeQuantity; if (log.isDebugEnabled()) { - log.debug("generateLinks operatorId={} operatorType={} targetAccountId={} times={} perTimeQuantity={} needPoints={} expireHours={}", - operatorId, operatorType, targetAccountId, times, perTimeQuantity, needPoints, expireHours); + log.debug("generateLinks operatorId={} operatorType={} times={} perTimeQuantity={} needPoints={} expireHours={}", + operatorId, operatorType, times, perTimeQuantity, needPoints, expireHours); } if (!isAdminOperator) { // 代理商自操作,需扣点判断 - long balance = target.getPointsBalance() == null ? 0L : target.getPointsBalance(); + long balance = operator.getPointsBalance() == null ? 0L : operator.getPointsBalance(); if (balance < needPoints) { throw new IllegalStateException("点数不足"); } } LinkBatch batch = new LinkBatch(); - batch.setAgentId(target.getId()); + batch.setAgentId(operator.getId()); batch.setQuantity(times); batch.setTimes(times); batch.setBatchSize(perTimeQuantity); @@ -98,7 +95,7 @@ public class LinkGenerationService { for (int i = 0; i < times; i++) { LinkTask t = new LinkTask(); t.setBatchId(batch.getId()); - t.setAgentId(target.getId()); + t.setAgentId(operator.getId()); t.setCodeNo(generateCodeNo()); t.setTokenHash(DigestUtils.sha256Hex(generateToken())); t.setExpireAt(expireAt); @@ -109,11 +106,11 @@ public class LinkGenerationService { if (!isAdminOperator) { // 扣点流水 + 账户余额 - long before = target.getPointsBalance() == null ? 0L : target.getPointsBalance(); + long before = operator.getPointsBalance() == null ? 0L : operator.getPointsBalance(); long after = before - needPoints; AgentPointsTx tx = new AgentPointsTx(); - tx.setAccountId(target.getId()); + tx.setAccountId(operator.getId()); tx.setType("DEDUCT"); tx.setBeforePoints(before); tx.setDeltaPoints(-needPoints); @@ -124,7 +121,7 @@ public class LinkGenerationService { agentPointsTxMapper.insert(tx); UserAccount patch = new UserAccount(); - patch.setId(target.getId()); + patch.setId(operator.getId()); patch.setPointsBalance(after); userAccountMapper.update(patch); } diff --git a/target/classes/com/gameplatform/server/GamePlatformServerApplication.class b/target/classes/com/gameplatform/server/GamePlatformServerApplication.class new file mode 100644 index 0000000000000000000000000000000000000000..91b74416115ff01e428b17a264507c89e52a1c98 GIT binary patch literal 887 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 literal 0 HcmV?d00001 diff --git a/target/classes/com/gameplatform/server/controller/auth/AuthController$1.class b/target/classes/com/gameplatform/server/controller/auth/AuthController$1.class new file mode 100644 index 0000000000000000000000000000000000000000..542d1f999872e4a8f013f4f7d0465b8ff7ba0332 GIT binary patch literal 1439 zcmbVM+fvg|6kVqjQ);*c!7CTFY8#P=*J=?(z=4^f&XmC!-wx@q1k$7?r+9htH~b7| zL`NU|06)S{QCA{^I)xV=a?Z|5_TFpnz0Udm^XoSN_psQ547vgXT;}(%!nD8(Fk*qhpAddnr z7`SNS5{d!?e>v84C{FiGE1`gTG)+F9{=ig)4 zwn`~h+WX12E+@zrToGyD56s?$>s-fRaGgXSu8{u}`8im?Rd{6khHp3cb%eah7B_K= zdtxP33EZY_LHy#+yg@St$_9@OaF3b8$9ezhX){+;jh+t!Kpil!oNEU)gNMvY$Kp>GZ#f~XSuaz{G*Oqq0?#hmn zrbl`=r0J2gP47Fsn+p@1HvQHQefl@`={viNB-@e-@Sxq9+4)`X@0#(y|GV}ffTQ?l z0x@)G=+x1LZh_>2xnvq8(=HlQxdoZ`1-d6J+wzYIbPSKo#?gbghJ=n@=mHProw89h z%d%23{W-@i8=iERq-*3I+jpH(i9@sM&l|`2I9Xd0=vAxJ+-v2fz=PRVd=xuwsWXXa zGD?xHI{J_lNGvS-HD33(;gzqtmcL>=S=%14N$J>zJ856ZDGH>rj$1Um(%krhk#&ki z>1KM+FRO%x=IyoB5?GD7ZcclK@B@~+=aUZ4z)6>>=b0lDELmu zj#4c9g1lUn9^vjSO8@DIr@)=VBiXu3rhV74i7w*~T*oP#Cb$J>%0A_~jw>+HsLN)u|EEa|XLOv! zlMFVqQYoznT)b^3G(uj}2s3!Y;y%bf2lN_wkgT4j&9--D;u6}PfXS4`KF>0n=4D&IYtR>kci zKCa=Cj%QSH+g7hiGxM&qtRhvQ$9KY@Rwe2aIzFlDQ|Gej+6jCbpV46I$RRH<)(Q?! zZYt7rc%YHM{$|PC%CrO|<}?&_%)=5G*jOb`2L*>=6lcW^E4{#;MhV2oBSf1UfW^J!=-tqiN zRwLDw8Kz5SsY+A3ji?(QxoJihWT@LTm8g2;wWlfRyzf_xGknzc#ipJTxM#gFGb@$# z2JK|iS!7Q%4Qgl=0y~XaHKe57>xpaLzfDM@gUku1utMgsGVwUrm{hf<*QSk;aEm%1 zIBVLbE`4LN>%fhoP)~ z_@;>?$j(T!!1hUV)M>fF_C!7?)-%o|*|G+-VmO}@* zu@SdgSr2NFpy=%l0_tDaG2w|Uaq2mBPEe_&;rr`4MePea#YDao-76B)PSwrJ)0XNW z+t%L{9#CFaMJ=e_H<6J{B%ddd=<-1@Z-q2Cg4gpoUOV#B#&cvmDOC|>g-D)o9N+U@ zvl5m}udf@wNZ^|brOHwaE!0rTZsBwiqYFTUd6YQ>i>HJdmB-_v9|%Ax)!U7 z_?nKFaV3c>JUpMZZRrMWUov<V-z#Ag1`@DG7|+izuC2%X1ETMsYYKnHfJizi1Z zb(;>}ywCEj@z~vk1@2np?2@{o^W8Uk4PtccDzwr4SFz=7F2zvdGlfn*2l(89I0mtm zjLTd}hh(tfa7G4!7!iz=pcpC~$75VpA3>?S|DijOIz?io<-j|*Bei{O6$96CPX|Wd zgT~26-r}cFy7~(Ou!~aDfzf7J?PIBtRgAp>eJrW1 z;^3R;9Ge{7zlOuW`*>sx9|cx%a&!$(sKHapmW}|)esTl$5XZfQVjm6=jzb*R(HyVY zHIA3?CF-yPcjL<(#qbreA@gHGHg&dp8L{K}xp}^F&Rz1YW_n_&rkM6(E^VDZ(Yi z_7R#Jgn{zy%;+j+ujAPc)FUe7y)WRchgj`FRvi!&&;FepB?QMnMf zP`P+bxp)AVz-uJ!B=gsq4?kekg}U7rh$GWf&-*C6i#wE7BJfVARf<0PA=hGfBS198 z(T_O)F?WTi{scdbSWn?+9H~6`Ie)*y@A0Q#^cVaM?*yZFag{M~ox2pDDZbUeHT)eP GV(@<$8HbSo literal 0 HcmV?d00001 diff --git a/target/classes/com/gameplatform/server/controller/link/LinkController.class b/target/classes/com/gameplatform/server/controller/link/LinkController.class index b04cd43277d1f66ae3a3d4359bee5c8987136d97..499d45f0eb4db725a4e0296dab92af8b811639ec 100644 GIT binary patch literal 8224 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 HK*|3DNCnWW delta 2018 zcmZuxTU1n482-*&IKyxT1{4Gp9ONPlAYDuiGeIsnii(1G%j(D+aTI69IR_2PP|I71 zN?Xg)5;L=_Y1&B2vYu?MUVCb-R=p79OTP5n>f19AxK^{)nSby9{(t{>&OmKniTkI2 z?%V^g7&rUfZT&s#g{1^$Dsa?Cf`%J*q-jv0DX^E7x2Hlux@c17il3Er>8?&AY{YcS zP_VzOx!;>BTBhWSs7)1}-a_HYED-l?>Gq-jGv(jZ?HYin!}yB(WXEVn|t z4AbZLMU7Y+k88U1uobd;e2aaf=dXqN&#qvB_`zPjY^|}o+c2$Vh8{FxixhY^RIO$S-HODj0zn0? z7#%_}BWNcK957>&y{#uo5UNnEVy^IcXN*ng?A7oX9#@drX;^iH!K&-%h;)Z7nJ=rX zym^PdN3ZVE!=2U5k#OfCH`6|;VIH1RkZS7NjCE0VprEvDl4q+G3(u*SggPuG`8v8T~;7$DVR1nDK$nX#}1SSWR@iwYGsxzW@&j8 zW;d3iK}9{sT$0m>CIU6S-{w$wr>US-7~UeWN=;J}Lj?ldvCj)E(-6RN1x`I0?dlQF zX69u!b%#5wP$bOBo3Tp8N^#2Nv#&;r81XiykW9o}e4kk-c4Rfo%dqsA#Bl;bPphSO z>|Ciw+w`qnhKfz3-J_6-p)B8AH@4tK6)!08PFRzeX?O{`f;20VfVy5c4biVnBaao+ zjUcwEFvMROIrBTQouG!oR=eKSO(v7(0XpqbFlEwi#$lv|8&(41*Q|3XDxzFLlJ`Yk zHzG)L!$h|VZXqBJC^h0?cE(H%dn8rd9C4{`b!-m=rR&QYdazIYGPQUKV_wy;Upf(T zYn5RHTO#a;jYdGG9l$=a(lo3FBiP+xjoVBd((pRo5L>2Jx~1z84M%ZI%+9WMnRrvf zTR0&$W*4Q>bW+19oEC?(OKeI^+{kW8b;Jyl?JpjCZ;QomIe*p^jGnnTa_sa2ac|`0 zmEpmY!*@=M-n}(Ca4`AC5$C0mh-F$aJ-X7cwnu_&aR48wxFqbkr4C%i$D%6tcN;E> z^gRC*d?JbenTA~mXQbd$FT!GPUZE3TD<~1Qxg~_~hJpef3&coXRxgPOCsOztIvJ?K z1shU%YofGKy8XBLRD2814c=_X;D0*5QNUCwb4 zsJnybfH+oMXRtjn^z;NsvpArSO%|e(vKq6ofKmc5FInh602X2m*0L!UM=RRcsywYj zJM(3-_4U*_(7SfWMjAZtXFR4hv zk<4B-Y4;w4u!DAnU?;j5F6%g9bJZtlkZPj`XanC|@{=B^y;Q_lM^^IRMP%b`>~5~$ zAh9_1O8H70uSt0@j>A$OkE5?b4w;v7v$CccOFS>n8j3zB{x;6qv^idX1)6`zw?5{oSQnEZ-= N#f4nMb$o-oe*qt~vtR%K diff --git a/target/classes/com/gameplatform/server/controller/link/QrProxyController.class b/target/classes/com/gameplatform/server/controller/link/QrProxyController.class index 04874d1817144b9914bdcf6a8469d84d8cde078b..9e2cc3e76caff14f23505076e1a7a6689f532829 100644 GIT binary patch delta 1159 zcmY+D>ryvgRWgb*tPEP>K+3lypp1xqhbsZ#9)(bkGm14IgjU=t{|TJhRx z>lN2awO;=NS`-U2+J02W&wg{{lQaGkj^_3hlQOi>s;INKeRX!p*BNP} zU9;10H}@zy?7Guvl6^Dd=lbR*v*Ve(ZSc=W?&UsBm!X^c71g#&SKFWbZIK@KX!aWR zv0qVd*LA&Z)+Yiz^cfEDfW4%90&N^LJjg@#S3Tz(QY6Kp(vAd5)FU<U;lmQ7HV`9SDWmhiQ7bY!G04i zcWIYHT;VOv+lF^|*WL=(+rPrU>nQIl8k+1(IMKCn$h(F7K}e3)8qSc9l2@34TrQJ8 zkWCi~nSvtxpFV1?+J%xse$6$vSNp>i;u;b7g(6XeBPG!Vwuzue?u8=e-WHj8W$xpo z{C!f;L5c2qDD^!m)$$$sx*!k3GDd_8aU8iEL8^F4Q27R%rx_6>c|}#lDVh6ZhY}Re z2+ilpFEA?nqDspeC2%f##m8*(>pEX@uFOYXNyvv1tvuO^f0QxBvZxs99hYpE|6nJSn_}r&&zkZKsp+7 zTQ9(E%{+dYLHA9z-Jo%m9Uj?O#|=7fvU`QzRr)>LrY-ic^8<%ZdSge2RvGlVzf!9_ z?qNyl-z=_5w2-3w@{-EfPKqQQ@|wCNx<#4|Cko68a+s6R!`WgTZUg28zu<1NSi(8Z z%j$~-UgAQ5mt7ksMR8(=%!iXw&`w~-HJZ7 zprR;V%I^j7#`xeXNU_p7I6Ui%KKST(8Ap6^#y1|EaXg#KXlDML^Pm5m?|kR7zomXm zRek;U>Q?~z@G*z9INV#yp)kaz%xBC@(R2!#gSjbd(qB9^qA{qwwqyJI#F9Fgh(LyJ zfWu&rH@8h_V5l|_f+}vQr`a}fiEm{+OBeYktVW%5^VWlIoD!uC+=bS~?}yYjba1qb zG~1mp(1~>n;ezFll@B?EIAL`e$Y87Zlyz#|xSL};LsBfTWXQk{>=b{op)^B$^gp8G ze%W>kJq$|8^q(fQqB)bxn_^V!)+6Y}K8`+yR`D}$tuk;A?q!hNX@*_mJ7vANBqwzZ z{TSpJU}zDuatmb|!m#*V+M#7}KgS5e_8?kZmkoM*0HflVd_p~hhd9Q>PjWLE$MNtv zrAwQ@qa24B(uC6>{!jw{BX~@h%Hi+?9yjm=j)@yeZ#avm44B9XB{Zkx88!t0X4dyh zSYFODd@i*Jp#wiw=s z&`8f2*n_=fU5sHbgE8VbR(YUkdY;p_ikOfPQ_)DmDQJ+OMLja~Ydgu?1Mhw#)Rk zMmA0~gEXA5qJ&mQGB!`9=6|cW&A6VRcTo;bHS8u$y3Ktf5Q_w(pvRy!9<_^++;a^* zSFnEt_eoUQfh#z84Ua72=n9^ca0A)6rCdkhh#a@aS1>IHruG%M5-tZtt+A`EbY=rl zX@O1zQdCVh(ufHsnyd*L6wo|D@>$B65Er72nHNbrjn~QkCIsHX+w_{C+dDXq3)IXk PeZB9i8a^QTk*fUz8DZcm diff --git a/target/classes/com/gameplatform/server/exception/GlobalExceptionHandler$1.class b/target/classes/com/gameplatform/server/exception/GlobalExceptionHandler$1.class new file mode 100644 index 0000000000000000000000000000000000000000..9851068a045da6ed025ee6d55be72eacd6ce71de GIT binary patch literal 1312 zcmbVMZBG+H5Pr5TURw?+ff=W=D@Rnfk^Y*%w!|PtX+oFCk{v{JZ z;s<|#Kgu|JEwKssrI*~z&d%J-Gc(Wb?>|3(0eFsADZ~&rkTB7MYYZ!nU$<+#E*c(J zhkj7ELlK;az!skz(NL~0?KhrZ;oioDzR6|P6G3i~;hH*f!`uQz+3Ge-QR7LPNFmLT zJmFr>@vDM?m9@b%(TD2{z1mP0VaRJ_%WfU>6K;E4*6e*1xUyDEBZC10Srda8Vi=7a zn#%R;Emyu5)lD8AZSw{}F1gZGs|@jc;UI|-hJ;R-#tqywaLdFP#u*0wB`8ZJY9e4T z2t!ls9x{yN%Y_aIZ4bf_!yOZMF+tHAO~tU3?{M3#91BMkFYk25YC9!yj}o>EP9n#U zQZA{A*Bfa}VcJ06L;=+Q{irWix1YZ$r3 zB12|ds3X6+#{*)z5&=a_?YlL}RWqQ>Yb~Ug`BLgA;lJ}+r3C4HzZp2@vZ%D`ULtPKB*kYEY6v4X3 z!%&2nAQorns)%PY`cMKS=?q4aZVa+8dIw>X-vX_^AdUpd6>H`c%o;z1Va=VQ*ZP5e zD?4m`hjEV4Gu(b>WhY7NZ7uJgZN~5nOOaeAXAsCD-G48log!Y6Ow;c=C_R4x DdOuvf literal 0 HcmV?d00001 diff --git a/target/classes/com/gameplatform/server/exception/GlobalExceptionHandler$2.class b/target/classes/com/gameplatform/server/exception/GlobalExceptionHandler$2.class new file mode 100644 index 0000000000000000000000000000000000000000..b43214490b847c6359ed6115930b623919ed850c GIT binary patch literal 1439 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 literal 0 HcmV?d00001 diff --git a/target/classes/com/gameplatform/server/mapper/account/UserAccountMapper.class b/target/classes/com/gameplatform/server/mapper/account/UserAccountMapper.class new file mode 100644 index 0000000000000000000000000000000000000000..27e4f343ab50c8b31477c1be4ae398f9cde6d7da GIT binary patch literal 1564 zcmb_cU31bv6up7+RRN1ii`8n2)+sOMwN9-w^udu%svWUDyCe&24M`^1;NTDNNBQ6n z@JBhG4Y5lFe4sw;V4rkClgigfwt{AA0`1e z=+l9vi@P!u-r#6H)3TQK<2&3nxhI93Eb8hA-JEeb^qq4SLRj)JGN>4*eWc;Em*#tn zBu4zBh(yojSAe$X`I1TDdw}j+emF2$!0aJ6MGxu7WV*miP*BZ{nHyuk>h-}5db?oa z8_idoDs&u!tXXc$hnF{E&IoYkg$J{+g~tc0??S6%P$4}upo{~DNtjcLxa`8(SQ$Il z`+{=-ntYT3s#BJ87DZqD5S^BTG R@DfU0u&cv8gijNm{omUAjm`i7 literal 0 HcmV?d00001 diff --git a/target/classes/com/gameplatform/server/mapper/admin/AnnouncementMapper.class b/target/classes/com/gameplatform/server/mapper/admin/AnnouncementMapper.class new file mode 100644 index 0000000000000000000000000000000000000000..a4a44f536a8a67aa8366115a24f3b030a93d33cc GIT binary patch literal 1255 zcmbtTTW`}a6h2PZrY-H*ShsR1x5A)(!H+z2AgvNeg-kZ? z{3yh+dr4V~K;ywmVxRNfob%)7x9$Gp;XH@QI};R`WC?;0R>te$KHg=3hi6#t~ng8_Ak!p(Iuwdnyen zOPGJjsTkvSMp;onZ5NW1r!2}jfr^kA1KK(1-B@yeM4(|vmcb!xo&-!IejVMSiFr;3 zn>k^tYl1wDA_A@6Xw;uanQIYIPh=Xk?quStk*X$>jHA@rg$O0nd5W9oTUt(T?Bp%7 zRekiKt)5b^|A9bre$nqF!_@H}Uaq?sDiv`i2U~@^eAzSpx1Rq~zH5~aXDg*g+gPoo z`Sq*{U#u6}A9(GDURpHQT)$9x>ht#^!tC3d!}7|^L4^Q;5{@1~4QHne6>z}CuQH}< zHgPpfO&!;*460bvfF^z{igv-w-0jV+J=p&{)EziLb^}#&poNb^Tt~PZXj|^KQ*gJ6 z*F)sI3->JdeR#0IXqKRZy}#o;v^d>T(cCFsuR%V7$AxACb=`gkd7r@3MGDh8PCGe?dCg-N~?32E^ zl}%2$L%FAfT5jMxL9TPIF68tJ^HHqgen7ww$kP29VwKCki$F{qetkahJgFkhn0ahU z-==KNtP4)X1h)gqk^~x6AxVD0oRAYJ2oKwUc20Y@mfRl_sLE91a2Yq}J(~S23A{`< zXsmpJEgBB{ao0j69BPU{p{##Y$gT>0+@RoYR(4lbt~EB-D7BNll#_4E zIrh06iHzs^XK8;LD$CbFzUR|}k--9CY4;ou+d2yEZ_(+fj| zvaL-omTc`dYx15FKyQe3Yg%O`v>Nsz6FE_`(JCLrM;apsheu;>5+-I2#wQ9qoD}g`dWO zAHa`7ecqO?v@H@UhmqIgnfKnjonOCy{3N1d+HX?8=uKo39*aaSwQzHrCOnhrN~Sy! z%OwsGOXGN`%(t;{(c-koHmS~N=Ul7=*TTg7x5I*pz>8{ z)0m5;h!&EoDbg7iWdSd`K(etCI+u(Z%D@23@^)}Hy~7Ekw*KQ6qt2x#Bk!X(=H(4z zCX?Z%SGiLfR%Z@+nuYPcp`NMlUYMQFGYMhsGZh=*@)XIh{{VJ$w>eHAVmq?1c)Y$A z-@Cy#`~aYr8L?zoVISVHt$%>Z#r&U_qcn` zUA@gZ9Xy!HZC|en`|N~yXUD;2j?x+xPT4urEoPhg$NDKZe2vDN!fqU0R2mw+-Kwhd zs$-i6rRraioCddazzF|h0Pg@e$J}o@jZe%)kv?}ljZy*#>z})bX!9?^6LpLC&JS(d z@tH3i8=jk0$2E1LZb$0x>A@pv!Fk* zeqAy}s;n0UEX3mv?Zz=A6*dyruaGI3`)@n4qk7dbnDq)}pWy94GRnH#L`NZ2JH(YU zma`mF*oV++DwOn4&Z<1wNYqrRltRd^FD#6+=cDVnV7O&K+7sWwCF?Ys9!J7_O_(;6 zaw^f83~myLXya8F7*lze-nz|n~o`-#RV zTxk}eLDc0V<{Pb`|M;Fm>r%wtQ9;V}`ddf1ydm!`Onf=wJ7mI!&Bg=|qU8i?Wc)+y z=n75LoUUu|H^KtsT>q83BX85JMjDOb@+O*2rA7X9DY*N8@ms zq$%YzJ;X_7nu$9VhBy`AG)vc!HiDZY`46~}+?uC_2rr)siYi9wim6y($}A$yO}Z7u z%x8Kri-=poT8`rPGb(6YnMGwTDsxGh%K*4dcc7areQJzW@L0uK!&=8m(cM6~^)VH+ zqRdrgt|8S1Z7MxwszK3L;B=4fM|iX808fgrils2Og23&x${xdvks5$6(E}x~gdZkv zJQJ#U7-wHjRFY(0Rz(fKZ^zloRD{ literal 0 HcmV?d00001 diff --git a/target/classes/com/gameplatform/server/model/dto/account/AccountCreateRequest.class b/target/classes/com/gameplatform/server/model/dto/account/AccountCreateRequest.class new file mode 100644 index 0000000000000000000000000000000000000000..a8f34538efe48280478607472e500fc61befd8b0 GIT binary patch literal 2841 zcmbuA>r)d~6u{37gouPfL9EtV1A_7pH-J)~2nagZfRre0wQ8@)HLPZL)7=eFrysN( z9j4T&)2X$cKBnylYF~rQ*h+D%-}`Tr4f0QPdd_B(z;+owG&8xcJ&)fxd+yo4{#p1F z01m_3>%j*_0VocFA4(WhUgqOmN^&(JoxFHi#7qVyhh$YYyBHKTHjS3TIw%dm`XH1+ zkU>{WQ=|k}L@LS6OPa1ohS0}_E-6}EB&E2iNjw(Q(yA%-Wap#0;HDT6@1%u+#@D4$ z;nce+!JsNq@EtXESxp=yZ_fpxf?U~>D!QV>=Yvp1hb4x|&9p&B8-h?{%cZzsOlW$X z4qphuCfLlNJf+F1Y4mc8EQY=+SNMu(=!wDR5u}tAF)ADK#iZy_RSj*+nrblE6_GW` znBa*7hBn?IY21)_K|oSOT;@_VHYOB~rpn^Ni0N{Qv>61KKE0Qjdbl+A$ogiQK|oA$ zC6z=7f6wv$p;HVhcrvL?aCAD#lb9BI(lRy5gqW!!a=ta8Wn*nw1#Je7L~6GjH?Je(8wnlG?P=?*7BVv*20YSTYJZzy`2)Wa9~7gDVsg<;E?QvM0JOsH0g!SA!qA2c?R4Bh$LMBH&f;F$b=po5 zw%|03%l~Q>NE|&MeLWnKPCHne>MFk&J2d&B#x_iuwTOQIlBug4Cu^?>)B1v^+C%+MS(yJYy@=c0)IG`=&xIli_p+wNpokI#uc- zRiWz{v!LZzffw`4{>&^DG>ez^cu6amS)SLjwyCj9#w;7Q7ImLn+$x%e#T5$ZS*(|+ zEtoKk+=^J>4V8MRSE2SYs%?K!L~vhST*@x#USyw2{il%zI7Iqcl?KIRn`JY*Y>BBi zRT>t&-9=M3Y-^QahZ!e$M5R%BOQDWTi8GsLquBAVyO^yPxRx+8EFXiijeic^d6mYU zjB+u1nz4l~A|S0>`c9rl4a3CRIyS1%OhPv`YoFzEIG4Re&19CwY5`h-XLY8fGP}IM zRut;Waw}8Piy|9G@Xz6|)q@xDm_i}`IV%+NI1FW8A@%sd?+}ikzO4NGtwO=*?e*lg zLOm>>H}@GB(kx%*SUwnyZN!t?fg9jmp+ z;wkS{J^t-+<>2eT|M>CMFFz^NIvO8(4jGSpDJ2Nnq<5tO3x3Zt!Heu!9>GxZ;Y%QKwl+7yrGq3+B-j1zOqu0UhTqb~l@9nm`Z@8jpPH`n{r$?(1G<3kGk|6k z!ic6q3TB9U@tnZSMT_31OBP+mJDP&0jyP(IP_GDelER--z@jPf8W269vCOmxoPmnw z&{$?xsB>PKIg2y|qGdFeiHN{?sAwCF>Vi-gp`t}Js#jgL2MW3^#%tKAhNpsOaOwpq zPw^6a5V2?6c`AgCAyBMLd&#*@%7|G3O#{XpFAc_zJazMaFUnt6er&{HT{f2 z{-w`5*@JF`x3s`=@93rgf@d9`_vr%(Pq&|ET*?!rRT)pWpXWjo9@iBfPmja1CgnNf z=b4c5#N<3@{5%(%@VMslc={clbt%t)pXZX4=a!sjz|V8J36E=ck7v-~xh?h2ke}y@ zl;=aae}?=#lTCQsugc>Yc6j3Sk;Fge{5)YP&&QOI`RAOUXQ~O0`yG2cqYlr8lxNJ( nGcDyw%6Z28JTpyr+|J?gjDsgYcbsw4X^dSssR{hh`aby&3%bFN literal 0 HcmV?d00001 diff --git a/target/classes/com/gameplatform/server/model/dto/account/AccountUpdateRequest.class b/target/classes/com/gameplatform/server/model/dto/account/AccountUpdateRequest.class new file mode 100644 index 0000000000000000000000000000000000000000..4ee9faf8b03eb36ee128d82d1e37440f4aa415dc GIT binary patch literal 2272 zcmbtV-BTM?6hE8r(Lj*MM}=B!N=qA{bc57tzp$auil)dkEf03Ab4jjYYqA@6H-Mc! zv^qGcv}4DSR;Se&eZY<%1I(Z(wDRu1Aqnu*|G@EgHya3P7$1Ddz2}}i=XZYR+;eXJ z`e*S^B05EHRgi<6N7aJcwUf=g5r+>9MEbw!Py5Ye75 zN@$8|8a)h2gaPZxgAHl`m8kIo2q|$sq!`L@j0aRz1B{}nhD3*giY6OlEE+`?qg}Gb z44G{j$Z;M~m>dd^@HhihWrQ1HT}cRUiQKDSKFXvPR_B(|-%d(Y&c|6i5d(?Rz`4GG zixO3{SWFvZ2s*@KsDSv=d%k}_A|Ggez;u(zqb#PNMgWw=FuJ|nP>lS+JengCO!(dTFY|a(doBsUAwNIX8zMAn`#@|qePiI_Fo#-;B5ZSm8Pb1L{%=M||^x|}Sd1C#$rS!u` zT^&b{q<^`;`t$V4ACv3%=S6;(S;w_N$254ep$`W%#L7$us{=ZQZy&C1_rHyf`^R?zp zhCOgFGV+b;MO)?`1ly){2t#$An{u;O*Y`T|a^*c-@6jRx(a7Y*7?O_#}G&`UzxgO6SVp3MgBqx~?iA*q%M z^bYZY*>IhJYJd#576EsF4npJWN1V2PY8OC7D$?d z;GkEriqC}7zJ}GEHK1d394CoR&`GRYo#&~179aDS8;d%hqHb6T=i}JL&6Tya|4QYB zp?6u{JF^ycXhBQdu|%)KuM`c74O3Q>PgNnG-9`BXiu0)|0Ghi$B-2P`(Sc5e1DC{#;GPIv{`TS}=@^F2(<)Hr3`25kyqLjb$fVJgMK`hxy-oO8 ztvx9MhSb8`J8v@d6(0F-CW9XAPvbxqz1I7TqkZlQUoLyXT-2e@BN?v9ko&qMJzg@J z3&+vr!0EGfa~oh9iD3e{bb zkrS$A>&=ka`szl!@oDwD4;j*OP58^6WY|C3R5Up?JxVxV1qB(nW+_RPpwwr4vDP$v zz%Wj_FN@F!z9KwTs;T1+DKw!_fr zZ%`jl?g}c9vt@r#h6{pfWh<&3;T1)w?73k~nI%QVd#&*Qx{B`K<4V&~FNXdxTZ^5+ z*zKVn>d7|Tz}Ta(@ghytThc7)(ghJxvl|(bOv`bu*}V({Z5)khvSNs&4LI0JvV*fM zUGut3<8V&d6b@pyzM@Z@lcIhB9Jx#P8CD17n#%Ryx?||ihLHaiK-K28@$7r>W8R&&d(PfTX zR2_>6a5^!(fXPN2PP>iMk-vr94f;_JU}->_n$8`&&Qq8s)Q$*C)R{ke8@VQZ-8)zF z9;`{}YYx15FKyx)nwC@(iX~B=`AS|J|Hd>kN}BOC{cXrLj?XDfX-XQ)JNFXE* z`~ZFw;yDdz5&{PlWoE~oH}mF=fBgLRors>$UY!D3sZuGVGF2F@pNWy+sn7|3-9M9& zV^n#pv~o`wt+YG6RjScymFgiiC}i{?G8s=qCWonTZ;j1(F6~HKo|#ytJa&eQ!VP%W zBuXF4cZJMRu~r~U1I1{gd)e^BS*4Q$-(oGKmaktMiadXBY|LoqxX?~zvZr#@PvtYM zjT258oipm7%DJ#k@R3MWJU-?TuACK0yPO{y_Z&l=A27N-U+470aK2XQ1*kJ>b(NNf zMb?-0RG^=yY9f*LgjGJC9G2WbfxyG=e+U6GjYPUPQ!zH%evse#Pvk&SKAW`F{xhf3 z!{%N|H!$&$un^Ws3s%1R(NsWR<}#|En8HT#rShX)ncdHQPl5KZg#b?^zz?g2T}M$C$q z5B^NmkGPx#HY>8QlV|3{m0mik9+e fF7jzE<#T5_pXMT;wZHK3YESvJ#(Z{R1G@VQR-3!1 literal 0 HcmV?d00001 diff --git a/target/classes/com/gameplatform/server/model/dto/auth/LoginResponse.class b/target/classes/com/gameplatform/server/model/dto/auth/LoginResponse.class new file mode 100644 index 0000000000000000000000000000000000000000..2557f1e0e9d426e7d991d4afbb1a25da866a9e2c GIT binary patch literal 1745 zcmbW1ZBNrs6vxlq129$?j4?q(=JPg``hX9BnxN4HG9Mzy`?6g}ach^hBl@9CG?AG2 z!VlnwGXBqP>AKpzF-v;yJv|S<^S`J2{paT|B6>obla!+LIAt`-(wLx`W8=ioJBHQP z-y9yxrYC6Zv1ys!Q$gu!?O=i?V0k7DM>;v0r2IH(8cor(p!KHR)!Rl__Bw|5!FIa3 zE1eVR=v})dJ9^8rb))Yc=?%MWTJNOWvn^K&%6axjY3+aRVP9+v%I|rOX|=bw$c#p_ zTp@2Xo6>dnIe_hR8kJ}sDdeY~=}33S5+ru{%{h%0IAWp?2F}gK^BOJD1>m!Br-f!C zZOJnFgm^@Q$S}4t1f##=QmZ>@XK?K)sKq_wV5>y?>hA zv-?g{zBGfIh)mTQj}cwMou@G6V|Zdhu}kqBsTFghR!oUnF&Jva)nlC^!Jh-36`VE@ zC$Q%0KS_cdCR_hbxv$vx3AhS! zM}o6q@C~ZMtAh8NSXD3e)uHl!w5FoVzDE$veRJ1>YKYGY9GIt`$Ww^(OeONHCi4^q za`-&cBY0T-kY`r$+@xDDRj}8Af2L3I3k*?x3W+>xDu{zODUBa`uCJU@G0rnHf`_Ld zr;;N6i4vzG=@A2isvrfgQvSI~a`4dn wEXH|CBY60$2zi!}27hab`YgwJ<`a1yChM~t=P8fi;jc5~Sy4QX@J!LhU!?B>HUIzs literal 0 HcmV?d00001 diff --git a/target/classes/com/gameplatform/server/model/dto/common/PageResult.class b/target/classes/com/gameplatform/server/model/dto/common/PageResult.class new file mode 100644 index 0000000000000000000000000000000000000000..e70f5307d34f3c956687aae3bd04c84db62b478d GIT binary patch literal 1893 zcmbVL>uwTJ5S{}I6iP49LN8cLy~0+zYFkZ8ZDLGJAgGNc{NK`*ZnLn>vNX|m@eMT5 zq{PG@K7bEp{ASN`>Gl%hkKHq8&dhhdZ)VP)zrTJH(Mx)fpb&*)q$DXqQ9-jO`kAg- zdb_E;KRhuSuAu0y**4uhLE%EN9;XS4$0(7cNlFUZY}hTWske+%OLsroPD|?;&Y9t8 zE&Ir@v?JHn5Ye*R+P>a2J{X;@1;mKy8m$g4t9rL}UDML4X2&ft`gD?JXcj@P?dp~w zQDJX7NpmzWNI3-#oMm=qleFMDJLYFN;|FH5t-DX4`nz zZ5+qU|&ME5YSetl*`3B z%K6rCkL{y<-9bZK!vXVLFjj*22@_4jEz4G<3&kL+poL4$K8K0UAagEwMTxmA2E8(q zkNDP_>@6m$0tdi+hf=6;NDLu7Fy73Su}6g5D+Ny~2OM}!=Obwqc56FQ!^rrS_Aa{w zB@XPa(=gtc-1(W|Xm0R4(i%o9gx8_qk0~dp!7fBg_%NEDjbZdw%pcYSV(@(MU&ihg zR)IC5{v`1OMwoK=^DzPN7XA#109v8jSXVE2^4Kxl8uA$K3)U#s9K)&WJ&LLM9!;qk zrAH|>6X{WAc*(LCItA|26bIXB@SUd=fYRQ@TL1=>e=%E9AzQ4Cb?5l00f8;n7x4&Y z{j(Ly<3wgIf#@CBDFrYD075DuiTsk?MZi6}kJO8WIj7in1dSGEeyqaCPCNkYLn`2`^BjuKg_qQtLSb}#lkfzxMyNyfLLK3DBKlr=Z*;4AZ@_8Kbq&1 z`ijF*&WmGmenL+Nocoo}VHSg&m#*Q=({%%9o*+TbuH>8va$X*j^XAo@M_!JcmfSU* U`5oNAnI}Hv&-@l`d%NfV0HY)nU;qFB literal 0 HcmV?d00001 diff --git a/target/classes/com/gameplatform/server/model/dto/link/LinkGenerateRequest.class b/target/classes/com/gameplatform/server/model/dto/link/LinkGenerateRequest.class index 19260ea6b8e443eb4ac5912ed009593afb398180..4d8423ff57c72cdd4414ec6ab9f09ae1c208734e 100644 GIT binary patch literal 1064 zcmbVKOKVd>6h4#Y(I#nAQyWv?^+i*~QN&GK1rZb>YHcO^$;~mHdLQxLNz{EoTy-Jc z6gTb*MoM-d&-*A(|Wt(RzPX(K#(Bkkh zppV+hH`=@uG`H5q$>W-iblv4!z8@H6bl@Y}rK%2O^jtL&Ms}{rKt)mw0n+1!R&w3h zU{5Uz$~8E0Lfx`#LFL}tz24rt-s?9%wsvv;zPn|Ace;Wy{6cvxmjxxRUJ+F6z2EL5 zEoP_t^VPN>aa~aIHcE$Rl*|v>ULD#MG=fnL9Oc$jsO|sYGHEt6M6Xo;zmX_nyvfFP z2$5zNDlzQ@B>Dp>EyN%yH4Ohgn~k8cszOZEaENe4L|z?je-W_`TxQpUcIfaOZEG#Z z4E(a4GRbE4fAFuT!RKJ@GcM^UtPN$)$LKh`pc8Zw_HXh>%5?FVpdmRIOFl)XfwJT!cw0?+@!}`S zjHb@-vrB!%Ahng%uX`T66c!Lp(3x00lcRbjWA&Vk*E2b)XX+n%`kfx=DeUVx2b-Yt FzX5Wk=B@w$ literal 1446 zcmbVMTTc@~6h6~Z%B4Ul7s2}lwFP7}#ur2rVxl3b%Ejob!G2opWaQ$FH650B{Fr5PSr> z6+@#*rtx%&iKm9CQHz`7+@zY3;3=9A22H8@Ga5(pfa~03f)DcN8E%Onlo1Gzv2jLI zOi$9sBV$|<1Oh_UxJ95Lei-Z11y6GGHi6c`j4l&~RZAU7@m^gw1QV*EBcd~|8q|8h zl9)=zZ&HIZhv9{_xXhh>CUec z2=bRqOQ$#i-;L`8>eAeNf)WNY45f%y1S0m@OaUuV^Xoq+X9$p61Zr85>!Mdt3{>5h zz^eu*@N9|esu{Cb8kQ7X4dTK z$=vF~!R~Y+6HoGsuk-Vt?d*Fb*`Hj_ZEYOvP7x^YQFT?^CE$<7h6$A2!)a83A5Mgz z0UEIcoCklD(MGTmhHb2=K~azvmrA<5Gof-ux01bN($hEkahLTaoUGBT#Z@2j%8EgsLmOTKQnfaHGsp8VjG z^`jR=FN|vio>W>;1=SXWaF2ET8?BYmI*g*aVzk=95{Zo<8Gc95h_(r7DXs+9K>HRn zZ{WrUEodb#9zrYHP;q|}PN7HOG@LuGcA2_K`UFoL3<8b{Anhxmqrr!e%Qp0K0m8d@K8{RX(VPD20y diff --git a/target/classes/com/gameplatform/server/model/dto/link/LinkGenerateResponse.class b/target/classes/com/gameplatform/server/model/dto/link/LinkGenerateResponse.class index b0f2dd88086a2bb4d69c832c302c2901c3a76adc..4d8597d4ff815451cf450e70c294797c48eaf73b 100644 GIT binary patch literal 1841 zcmbu9TTc@~6vxk&OSu%m0u=;Bym3=k#XDevqK2eiB82y0JC?zAx7nSdz8Zt@hKUJA zO$_nX7)|gRqwjtWZS~1-VEoT+yDepT@}V=?nRCwncP`WKe?NaEqA@zxKq0CMQ+0%D zs8*wvdA7jx6f=|h_1SrDNR4Vog(>8DjjH+wX6mVq>ci9!p+<^mG-6n3J;~BMlVb9g zWv6wA+Y8**(^i6~^n|qZlrV4WaV%H3$!#Y2P3~kY)8QJ0XPGqSCKHg2mvrNnnH*6% z+alDgL?Q{E$Qts7B~0n4i|rALQmaOF{BB0rd>oLSUH~c5T#s7@OHDv&8eeXt_6Wsj z2LugZU9%itFe^n0aE=^7h?`kc`OgSP%%=FbXj(^bxSqFY@xmjht+aUAmy?6fAkhG z4M{F96#E)E&0!$T;N=g;eogqIdzb{DpU{TCJ+@e`3dp}e$d*5k9sl_(7 z=U%4RqP_y9Zyu=O0#8|4+u)alYIkSQGd!YR9`)i`h47D1jTJAOH0r=tBlb@Gb~@CB z3%th77u~qPYutRX3m15GSa%~-h}c5vt&g)607UGJD@QIJ+x zUY!QvSA#LarqNI!Pg5mNTOiM&V4kK*p7t$xy!I4$nq8j5bR?iYEtNd6Kpvfr2Gysf zl4r*jJl<3kc%m-PF*;rdS!(t=wN>(T1n_u6G>mjk&`GLt`xZwqzi(}dtE#N)om+6J fq15OUti5rn#hCWsq(Bykt$X(X^4Kz_vLsF55;eFVSWwhOGcBiPX#wfgDVuDc< zLwq$x6Ynwl?%$!UJnZAN^VYCGa|zw)tD5X<;twCX0#zc|2h9^X>62{krc_Cr6wF{E6B$4 z^DhhcKCgV8E4*GREIj!2=*iDdUknH(57^rmy4cbVX zPz9aUsvSkNh$79XpRAkidmTPGv=dF~E?pabjPzI&95JYwHV3^4MN7R2%ZK&7Jw>eW zYow^oZ2#BryV;WI4U-lGNt z;K15|fdE>%Hqe9sUW&B^QZZ_+l-xqP9~fb*TajX7XV`1{Khn0he$95Q`c48y2Ua6U zpdGXmCq}zyH`afP-_f2o2*zl&xFxc9FYQB?Et|ZVxhwS8J@G zPhF_1VK``>{gFJ~l{{M_d3vLHx+{6w*5L{4De^S>Jblz3(Vu}zp7uzd12h!XpMgrA zt?TdvQ&HsE=<}F#5R$<>99rYs;YzM;kz7aV7-lsPIqr)jAR792So2ktxgTGLPY)-f Y6UYw6suttgiZ4atW}o;Z))<}o3oK}OsQ>@~ diff --git a/target/classes/com/gameplatform/server/model/entity/account/UserAccount.class b/target/classes/com/gameplatform/server/model/entity/account/UserAccount.class new file mode 100644 index 0000000000000000000000000000000000000000..0670941cfa0b9315c21002d36f4819db383e8706 GIT binary patch literal 2203 zcmbW2TTc@~6oAhZ+EQ5Tl|rF_h?f?W^)3Q}fH9g>CE@ZuY}c}+-EDTK82*(e8WSJ< z0sbiCIn#E#olIYRnKLuzGT)hVX7|tEU%vt16&y@L491c$Za^Fo3^JGeiknUDHq1}w zm$oGsBz7Fv5xWe=D%G~@oj&z|2h1KYo{eY54&?WSqF z!V%Xdw=A#Y3iA||``tN%m{Z5&YJ>A?p4-@__%{qlLx#ab2klR;+ctw-#O_%5PR}xD zKt8l|5rf=k3@Fm3(dI$$#q;a$cyK|AIRi?hNCbk5PC#1=29zm}>9*&%A~@ifxh114 z8L$jD8Kf-V=EAP;<4u&h6vAoQX3evB^9^cFa3!&C8L%onI_-MjWBd^BfkC?Fxc0|R z>m2jp=S`Uq`JZv$p>=O_TwFK-gRR>C-s(1kc*7R&@n&@O5-s{k!s*>4@HdM5G$HmLJq1)DI2FOf!kQ8zXI9JeLeDd+^309kp|=t8lqAolwx8!!o|2a5rM{o%Ri60~JoH9G zp0ecGf^FPV`*~62SU literal 0 HcmV?d00001 diff --git a/target/classes/com/gameplatform/server/model/entity/admin/Announcement.class b/target/classes/com/gameplatform/server/model/entity/admin/Announcement.class new file mode 100644 index 0000000000000000000000000000000000000000..cd8f5336ddcc6eab1b42fabf663b7445a6946242 GIT binary patch literal 2033 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 DRS#|r literal 0 HcmV?d00001 diff --git a/target/classes/com/gameplatform/server/model/entity/agent/LinkBatch.class b/target/classes/com/gameplatform/server/model/entity/agent/LinkBatch.class new file mode 100644 index 0000000000000000000000000000000000000000..792655d9095f5d61c434d24ed8a44f1926d04326 GIT binary patch literal 2181 zcmbW2>rWFw5Wr^(eNe8nv`{FNr=Tq;=L1mzQ64cNse*y<{d!%?VS9(yEs6eBnrKY? z;2+>0Wt`cT>#=UX@MY(A9y`CCnQj04{q-9FUcz1yA}|n#K?9-?W01M9t}L@*xpniX zdckeMAhzwej@V%^P%57dK>~*2kThTz3Bv@mkv!$DZQ~={{?~ z92t_{CHF1i`5lA>0~X;9o?`pl61=vHbt!ZhD3e+7Y^!mAmQ&nqF&Ny(`!h)6o%y?V zv&#KbtJ*+KR(hUUzC-)2a!{N*Ee0Ev+f);?MeAG~Vnws1a;Pq{rf6(+jJc9(E1zK# z-g0s7)s8J6n<%)C7)d;BmpVpACNVnL45Q_J(1YHMsUiom^YbVN_z{99o zm@$D7-A@Cxa!9CC*dMfnwrR8;ggS;5Mu(f46#5(m&0~;4kMN!{?Dx7jeSHgUA1Qyx zx!Apo#+R;?Jn`DT&EGiG>5*XG*J#dR0mm+aZ;n=cJNOl$QI`_OTS}Z=DRE+@#2J+m zM^Z|hL6oC_U4OW%UQd)zldoo$q)+CpBTw-5ET%&7m2zb(x=OH}O)F-3zjB9xw!xLS7GAd8L4-d^kz>}3c>sp>Mm1k1R^Hk3> zrt%c}@X$;KJbB5pq2-xSd8V~I&-6SKDo?Qw550|mryzNrYv*T5<(bv;ywK0jl*%*L zhlk#1z*Cewn_8Y3m1jZAv!&;mQF#{o@X&8Xz%wU#w(*bt|Mxzx@+@h2cHot6p66Ab T!HB^7P)j$tKRZ`=wuYcJ91AnYpv@@zX#50>CExG6*R+lZHM8{V-s`=m+Q2 zvFnakwO<{5(B;sAfeqJl!$%gJ$>k3-a27IY7*sF>%7T@$->|DrL!Z>0@Vy^2?4}M* zbznFAimuz*3*GQH+o|GVzcw3Tt4J>P zaRa@DKXNh}AG!@~7yYtRf9iy~gf(VeRd9`$YlcqPYSJ9n72M!ZpsTL$QRt?ETfA7q zDc4+2N7S5xJS~>4`&HN53aRIUg4+xT^!t`qiGoWCYzk%qeTv$4^p1kN94!YLN$u!8 z1*;rwom8Tz1%2DN7Z!}*KI^?!<46Z3=cta6EdQWGCvd6W4)%pLw`sv@@qe7)x&{4J z9q!;MW^?(To#%7J#%9zwmNVP(hj{S2I;{DX*G_Gpa;S6Y_z2b@e1Gk(YTK4(-E@4ORpx06;8v!_b?SB%mt+NHQcKVZL|WD&7j zqdE6GxfadYTgBGxPR>QGy;W>|)6G5Fww~(Xf!_+s`ngN#H{7}SOLXC37V|%a-=1^$ z#BT_`rRdIciT9jKyxUyj-Q^N*E0=f)xx|~tC0;i!@q%%Qmx@cgM_l5~;S%o(mRA5% z69({kA8R(27MA^mzrp&0yFI`sHDeIIz^7`zKZG@`S+EWp`22kEpOF3?8&l97JT4C2 zgh$wm2CrdBJ1|gK_zTkJ(i1#-BI*Ir(!`>@vfwd}>&Jt{!h$bF&#>vaBzm@F&#>v4 zOz_Z|#hwxNJP|#kre{j@Y|EZe(=(mmq1=f*S@t}IXBaZiYs~b_h@R*0m2_TXrsryc zhjKXfjI-y3=(%WmW<}4A?73)qt|xftF2$Zn_Pm6zh5fl~dgeq=5q72hxomoFCV1#h z$DV2S?1}p`V|wOA&ntO3NXgp}&E#$7atv(X(uN9*UmtWzVwd rSxfNH-{RPFmpwm-o)y!xA$oq4Ju9YXGr>du6U3fX_WXp;6#V=jpai@* literal 0 HcmV?d00001 diff --git a/target/classes/com/gameplatform/server/security/JwtAuthenticationFilter.class b/target/classes/com/gameplatform/server/security/JwtAuthenticationFilter.class new file mode 100644 index 0000000000000000000000000000000000000000..d04d60d4159d9a8c590455476d6e896a62056c29 GIT binary patch literal 7745 zcmc&(d3;mXmHv*rJXwBhHk$&aBB5ZjiKI!I*z9IAF-tI*nvfFNe%Lay?3ntKMXTnUU+f1f2({}bE+00~_Jzb`u-+k{%mTj@L|4e>F z@2=;bd(L;xJ?HqlADp`YV4l=#a0%|IkF@w311&~tC}3`lL|gnZBf8y)@>3s=2F+dm zl{?HuakI$?o5A{k8H|LN1w*D0)sQO~*&Ns&@P`87M*o_+W~1KJkS{2SL>v9F)@U%? zxHU@BJ0j6-{vAeLiu6XK&ZZ&A2}K$OMOD_0(AGPf{Z*01Mk87-@HFo*tI12S-Vn^H zx*0y5<=pI^TOSIBgXVl5QBqnX$gPMp7#@tkC=DY8;|3qNEKqMoqPuhyp;%DRXqYx5 zf{&C`_20506o|#jONa7X0Kpg?8r*^rRl%^aI^I%eMArxELS&y8tPg~00@0xAJA?Ui z9S-M|{7$zkt??iS6LgG+u8#eXjskdiMYAaw6O`Q)v1}@(+(xc4%%(`g+JMpl98kQpb^^vIIZ;jW5g0Uu| zaaAN7A$tYY!NzdFj7KTcFa1BWGdBYkHIZOL`TX)iOht)?X@WU7Fo7YG(ou@(1U-Sb z&UiR(#7x2b5(j95B;I72ttnfwnIldDzH?;655t^N`{luu?)*eG8o<(q4&u2 zGtL!DYuu<5+-j5S>ugV4*i+{F)MsY;?2+VC-O1OUR3qw``xL<{!M#~1Wr)xA)a64* zN^2BkR_j=UwKf!27=Z@M36$JOrq0T84eJC`t}9PxsT=DB!;~M2M1!BSUKS7TM~#k+ z_&7Z{5w|QDRdz5n%YCxo!HrEs$^e3iV`r6cJlKp+Xn1hIgJp|Y#}+(9Cl@lpjSAj; zEh;^zLxYBT!SH_2tsoQWAVC}g-yX&HJc$~N1;W0 zdP6!|)D6eA1hyF!kuYD?jX|@Ct(X}In=v-Fx$=D^h|M&3C*Z2Kye2QLZu@Q(GQJ)g}XLS4lK1-NVXi+n!BzO%Q+T_L~f|Y|M zk$mxd;`|qqUwJY4~8eGT$`kq`78fn-QKrjSCWON3T4yH)U&|)3HaX zC3i<48g}C`g8pXYsyN@L;Idyan++juJV9k=`Vwl&XR$#htnZa4FDA|%w}Jh6d_lt> z3P$xKwK8lP454%!!WSts%Z08XYzfIsL^{jL-T1PgIDJUsvAv15?$kA()bW(MW?q9) z7jJaqX|iqe)_3CN3GbDR??1-4Y1>?NVu^O$8l1_3Cbip zaUEaBD>QWaAi>A7aFtnMOqR06CH0VBEv{zX?oU;Kjk&mj^zH`$s_yi%U(I$mfH4R9e3w#OP4x1`my(aPD@XbxWwFcM z_)CG$F|U2kC3?;&ztErDB-*?C&b*}IuLNtddA@X76d170zkzC2GF{93fcZ|tK&tDN z7t!$7g2mS*YDK+@GM_}IUe&>t){wD0%2$D!NewF>^0zvEqOenFMmDsz8qtbC%qU_m z5c1&1_&b#vEcf6a@J|~4kw#)c(^6PPBorcYn8n3({4@TAnu#%%3K?c3ToqK0?UYQk zr(P8s?iK~LilNh6xU5b|2!xiPq4ReWM27;lO@{U7^ zsMqb^$l^fZ+A2#}%Czm@2KGCG$pcp=pKebaI-cl!)qeTZGIjoYI{qF1LE8$(GS(Xn zRy455ga5++X!!2|K6Y^=5;6i|dDcytp4FKoM1LWeltGeWCooksUmt7@gi`1K zO2@D9e*&FGvNkn2IOt6~l@EyDAv6OHID$sZp-OTh!VG^nsjBq~Qk)iyA7D%Uh$wdp zQ~HTRXgAm@Nzu*MMN`}=x8-O{lLF%4#>lRZ5Xd`C<|=k=fgz9TR}$qOaZ4c)CA#3Q z?9oHo^eihG$R?5Gmf_s$1m*UFdF7RZ3~+2r@bT7 zD8oD)i(vr3DirHc^ft=F*_k8HvI0TQ+HX8v+O>j2swIQ0iv3tc(wz8-zEM%_fBc!a zWaU2Xc?K@OnMa?;jYw^G04~U07E3L&YhNj=7-U?eCp3gH8MjJ9igUxN%|QLORe@Hg z#^|Yz#G~~F%dOlr@fxMv*$SQl@47f^ye&peFcxH$a#1)OF|A;ZZ^rcOa$$wgh?op8 z{S}dx)<~G5Boia~0GdpM15TwS=8^SMqsaz7-Tjsj3~y&tT&MRx%vmWJqVgMimQZS)R=^4<%6%2!*QYhRR3eOSM~A zY{-?_vuC?yGm*G%P1VvZLWflu4l^86Wnv?y$rjd+hg><^B{ZQ1CS89ikFjrz$qe;! z_Me0ej=& z<(%5Kj9(YOp6Q*qW%`WQF|mK&a2^33n~MoNa-y|=ti2kO@L|qzpT&&8$95hoBm6KL z!>!zU8`~~SQOD#pllS3d*)yXX^vm6tp?>HwSEmN(2s=<-misD37cK0@Vi#0v#Vl`b zH&*5%wQLnLkm?R>D9cmRwcflpF~OUcGjg;yuLBQsA<%)wbJzx)KweR}8?8C;=3T-V zwK`^zok>!07fyTgiayzaPd|&vYHqhTuN#l%ScmQ%v~Hx-zeJb^f#9kuzxC} z@9}EgXlFsUP?31mBB5Gmy@lzMJG}06yUSaUZlCjd((Ut#&IKiF3PKV1wi@{3jDbsP z;Ln@^ulr35^A@}bx7TwC6>7uxyYWL?7uI=>h^+IRwsl@s(W(7^Ve#IBw`#o}>A{a{ zy#*ckn{)Un(21XQ;qN=~^D^D5dnx3k+VHPlJTVg8 z0|y`8VO=u1OK#~9-)T#c#WJN^rdpyXmeN_>GQ*ZAF_>x>%Pd|){1mC&nXBYoEO+-G zdymyj;g7cQ6M5V9I)jIITxZpnHbZk24;IsMd>BPLnoKL2K^wY&#-#$i_NU&I`|g4=oAo#xl*S8UM{Qxo7Phq;=rg^@PojES-vRuy7{9_(HN6O{oc%+Q{)7!B% zSLRWUqg=m~`LclWo9wzG3)#xWO4qk!5nFlaajlWXY~|x!xg-^`1R8UYQ!E`VV{B6n@%>9WMQ)tcV{`IwBDkE zQU%c#MNpx&D5!u5D)iD)tGzGV+IvIjWp8__{l1ym&2F;fWB>4vWZ%5^d%yd9uf2ET zB!C6t5;wAttsqB5F7gD1t<~0RzK|Af^Q~xJs|QShy!pX!&|D~xU0l-Wh70)$+$sv7 zrh)s-NHE++@Q@yEGutij+9DDes-h6X1jck|>+~8U9MH^FL9?B!sHug`sKB)1`aZHY zo~n|8TatE>iV+wo;A+#&>P@E3+d0K0YpUHCjWG(&Q{ll_feAsww>D~oH|Wi#u}%;B zqIw_}37VUHSL&O1XGnX87Vx)g{90l}1jZMyskSL@^aUcDI!(jp*8>sVBtTU@#$$ql zi7L*ASD-9lbokn|4!tv^nXN{ogUBQ6^++F$x(%kETfu-%Ev(Zw37lt1a}L~-Ra}56 z0!3ONphu$(lHp~+aLkfU)JgKwR9uK+Vhb5maZ$YyY4b%xt+Utq>W#KGJyPXDslbZ5 zRSi9Rw#V<@7vK6w{NO$DZ4btu+19glhquBTKYYj8`=30!>s0*2flBY@E#79Sy>hRm zp59Y;_Uzf)v-|kj-AAp%_*O#ib)y^=3Z|>@VTQo)J|oqJO`T)~l=WIDrmtuf7+qYO zYBL9-%8i+rrC_$iF-Kr%AC7uMy32^-y3}iOv#J2|aIu0*R8*phPS#&q+B_I;H3Tln z;5aFMV|#Gbz@3st7kwWS7A#ocjlXmgRdr_PUh0YZvlZgyiR9u^$--pUK%sBK9u!*n3)L*HmdG_EAM%O$zR0>v4~ zt;r;Y8%uG8f?5@IxH4fOGuWZ~YVGKv%Y=;$QUFKGsfRSqGAviHLd8|MT3}@VsG%b> zSd`{iFw`QgJ&{;4z*O7kw3{Cd3RbFU#43TY=LQvUM|IP0>q=lo26+diu`O-t72v_B zr3k86i**#OGZdpy<`vgvy42thk`xj-G);PGqYf2eDeMpmyLe+~Frt}3BkV#a^J>Cp zC0s;B6l63v5YmEFXLSZMW$?1+SfE z%e}%sbIx3WDFXx^2yF$!{VE>7PTD3)Y_e7htaQXkt)o>R1mB1 zD{$clb7R_NACuTQYGZuIy)Ha1P$!?LlmQEL*Oe-wC2OsZwbYNjQsN%Ddm)sV; zIo9UFQ%upeozFhCt@rTF6!MH^aG9bHsdyUC(91ft2qVWyw=`(xbbM7R6b*U=&nkFM z#q&5S;O*}*%<*X#?6e>~gY6vKADL?GAWyS>M!TjVvM3){@dCOir{&tz%wR0@#tFQr z;3X9=He;2dqJwJzD7OUyJuc}py$y&l`gzaZ}PHLb6N=LO$B%b z-%#;Q86a+Qq*(itpk3tYZZ3t7Aopi0Uh3F8q**H}FNgg-0zi;BPEZyZDVcauw)bc_fMolkM?cDk=~uu>4s8jZ4= z_P@#AbaV!! zldp+|WxLQAj0VYF@@P>wY?xM;K%m*SB0A-~*DCLBFe2-G&AJwj`dV#e`n2Q)U!$B5 z$ZW1PDo|xpHYYO4^tBtz>9!18n3ww<*yB)zk=i{2n-C4pcD zD-6^~%8oT=qA|v_mu63E2q^ssdnc_Iu* zgfbl`+G(P*WT(o~eTE~2<2Q5C>C8{zC{3i4fxc=Xxyesfeu4Ww6y<$DR#LmQKF76k zyFhsc&IYD*JL$@3urrdJwlgPY!U#s-s1z+FQx(r#^8+F0sl)9zVv&HpBq$@ckT!AV z`RUTEEKKQPk`^7M8KWc0_|grNmh;uH&oRP!*d)ne)rMh4=`x*mEJh3S#3Z+vEG|&Q z6uz5?sjTvSp&bmbr^EYfMcGd&$?Ww|sw9x>#rGI6Tlt(k{x` zH3N92Ni;>J4vHEr6!Hg6y~-snWMUCbomxwiX*A86*%WAJhtg!neG}hDnykz~(M#N- zRFo;ATon~!I&TdSy0=42X{Iwr5auh&0(H4Lhwv_o6-sVYo6w)C4C0sU1s zOz_zytzC86j}&z$#-7H)eB3Zh_LOREnAy=PT6$Cwe07;RK#!R`LlN^h;tvkWD6`!N zllUx^#pk_jjFoRwTouXpG3%GlS^Ul6*p-XF6XGBI>f$<=ztyELK$IPaGR(Ulg=Hr& z1UQc22cd9tcx6thC#MUej$vG>_ZTKUhp9y+o}80iDD!sVqHfI1!L!7Yjd%EeEb{o@ zLrUXFdpx()Wte{n{M;UaK^A(~3F+$wP$HDDj-gHrp-p0Z z)woIwg+f~MMIqr_Vi+M+%QGbWaKcM}D1dlZj@wHW_$@aWl}oB1JzzcmHqspm_$Qya zv&0Bmf20^iPU!DqJ*i7hPD_nG(Wg=A`l$-tPu(7{b^AFBstcc&cIn39EE?q)ADp|< zEtjVR2bWitNqk>T;`>^1^>wYHN+jjIdVie_DNGo5;_`8g!HJE|RX}86gk0p$; zrSf@_Z;N%f7FVJL^)NZk-iGDaNk7<&tBLIz?B^@MAvADMT!~ltbeM=-`6fA9jG;dF zW12Wmcq|*API|y;%XY%Dlnde=>{IZTWu{!gBhaieK?p1TOtOs2KrR~Jg}0x_RGCGD z<*gD##(s_%$KNb5UQFPxjOB?0IiKqy?t1w>O%x+r_{2qGrkKTjH}__Xx#D7Y{s*wO BpI86@ literal 0 HcmV?d00001 diff --git a/target/classes/com/gameplatform/server/security/SecurityConfig.class b/target/classes/com/gameplatform/server/security/SecurityConfig.class new file mode 100644 index 0000000000000000000000000000000000000000..9bf95708d7aaf4fb67a18346a87d5dc6e0a7395b GIT binary patch literal 8649 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 literal 0 HcmV?d00001 diff --git a/target/classes/com/gameplatform/server/service/UserService.class b/target/classes/com/gameplatform/server/service/UserService.class new file mode 100644 index 0000000000000000000000000000000000000000..c8c89414be6bb54952d1439f42d89ca47e64f300 GIT binary patch literal 7377 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 MPx1%+grAY|C#O^E6951J delta 2382 zcma)7c~n$Y82{aQ!@ODEz%byFC?G=4qGE`O;s&@)q8OlwW;noe92#bDX3&&!w8a+9 zqH9)aw%B52i#tPU+P+$}Z))0Nds)^Wbx!r&2S+$r=LqM%@4MUY{_gMlzB`A9whgtu z`d8Zl0Aum13|-6Qf(#jY23x&%i8nXk4f=A+YU`38v zTl38(F!WH600Td5b@n%m>4fX$DDC1<5e@r;zCw@3Ih#M2cp$?J3H=rHh9b5PP+)@D zf*cH#aX!One%vrRL4gC#mXotgZVZ+&h@qH<3;8i7)07EA_*ypKG!%IVhN zrpY%c=&cE;b(+X?jVR}v6Us6wF_((d|%{hNi30MWMQx-mtepjjG`YuS+W8+mnh@g|3$=2%v$E_oi3*=S$CWb6hHI=V5CQ_86SgPQ1EaNBS;ihI> zDdP%;=@b%AqCgSyu3%W=n8#1a*?g0++}Mnj3RdAN{+n@L@-+;)dBqm2#`Q9;W0*oa z$0kJ@L&1pJvHu3#$R9IJ%Up+BWZX=ds>u@dH>kN2o5J3xKNM8Zf?IiSv%|C=8)V$Z zkjC3hX+-*V+`;|kiH41W$0i<1>djv>ryJMfE(Kd~H$P>bCR1`ZdZUZ@k4fb@;y(8) zcmT^7%$1YoR94R{E%MB;Lx+u26#;KUO`VtTw~ez{@Cdfcc$6VuQ{xRKlg@h#kMpg{ zLemcHlChIvYUf-&&F#h>UTr;(|7j~$I)Jh%LtPG@Ywwp-xhNc3Dw3hlIopV*c%CwN zfEoMojEn;eDP5^>W}$+EIK&THvMCv!Q}8@q;NM$H_)1&4(#bPB&xlv~V#^>tDY@Bb zMmye-@iuQy&LKAM;ywO*@{yt>1Ky%a?Ov4~F9Q*=;R7?(;l~Od!Zup?kqz5A$Brpz zMV!Wta$8E;ARCT%PJF50Wo_aM8e>pA!Jry033wwBH6r6%h8$jP@5M9ii3S1kzgg)Z&AxhfJ4y53*dX$acr!(vgC>ZO8}WDA3V| z9@{vIg*TaD4?H`O8pkw-J8?d_G5bY^{gA38*KTB0RO$P+qN1WIp`S2uR7nuTC5`w9 z?c^SGZXbFP)2P=MDa5iT(vgV_D*S$Mk(Wzzd8F7_WMKiawTrqs*kV2|B|PFS-e9^E zV&qoSGMzT)B~L;P`N?2^Q%5g@$*5&QO_iEeqK%*(0zyc)5I)+mh^_QO+mI!-?_;B0G})3y5-_pd32~&Nj2CRAMeNyMV4JqLJu| z<6&a*L>y1*v@GeK-szegq8ex=X}J#|6sqk`l+lzAB1pCv<)FRI<=%^@<9Jqo7SNDx zKsLOHm%s>!-hzJv37l8{AE)4K9HQ_VmWsrA9d8g9QJ9CxzDX^UlIneGAL0{ys(DB7 z8BS>4=lBXI@ina)O;!I5zQYfs@D6&pe>9jd3PbS|SvS>#u+3zDCL1DqitK8#zZgva E064Sf-v9sr diff --git a/target/classes/com/gameplatform/server/service/link/LinkGenerationService$GenerateResult.class b/target/classes/com/gameplatform/server/service/link/LinkGenerationService$GenerateResult.class index e9e11e116f23890fc5511e32f5cc99a3b7262ba6..117c52905a004368b734f59e2a4a8c4ed136a42d 100644 GIT binary patch literal 1760 zcmb`HTT|0O6vxlDrKKeZ7OZmdf+Dn_#0y>qkQv1rW37y3cu&){1k;2`wv2uipS=63 zGdRxp;0N$SIsSLkrX`cUIKJ%3?w-qU&n3VA{QN~kcj$JG5|qqPN}~ZvGaB794h-Ek zoQD3aw#QAuD7|JmmRM($ES7e%G)UPD1jnSs*HuZ+l$c^*)XP{Naff?`uw17K4P4E(Pxy20w`|18)C^(nZq@-&?oyOpr?D!d9@A({8qxOV-GLA`yt#v2-82+2^>=ZMnkae>Q1*2VpJuIe2`45DpUBNuo8IkTqjs~ z*rz=5<)N$2%R{488Le=%P_Oqp#hPzZhU&2~6mZpTc_x2o$-+;@_WhFVZS-q}`{J?d ziwxahwDRw5z)0J4Fk2h8;rkrbI(BrhXa-Y~z_6#VVrcP|kdve&Mn_3Z1Ti|Lz9%S) zZ~P6gPU1v|WRL?3KZt!(DpOeHHPIWI#;OGhbehg!$LK7b!+O;CkTPF!nV_!m+gRfn zIu9*ryaFl7(+i8=DH9F-PFWWMjdo~>CEv*C0_+CRZV(vZSf1f1&-+-Oi}5_eQJxQd zcx0|ao)N_}NAofH8IAIMjO8g(DK0;wQJznIcx25(p1k5&pvAV!Zm|z(Jj(Mqh9~Hm zOYnG^mME#}R)({%ZsU?G*;Dl|eYk=i)S(@;QyTy2i7sgY7eTNqaCa5E1YM)+N-on) N$Q+ahX_;ToZaV=k*4YJm=T4&(* zKtHGNooQ#<_x`9(?@F?)kWHc(4^OsU&B`plo+h~vQumG z4t4{spGnoJMW}XA#Sh_QEfC@JTAhaPFhs?*kl_YJ(AHwQg5P7*3$z2{3}(0a4zC3~ zY}cMNx6#)OoF>=))@qA3>x1384BNLExFKR|U5Zdg49fVTD-^EKq0>pI79FhBrO$)= zTw{Y~bjI;z3)dtaNCA6V1Vk~?v{~5@?U3u9LI#ToNVa_^cmIY~f*9PTBNKN-DD+(h zV@u0V8I0c}cn9Vg%nay0P)e#Ye88OFH$#Py40f>Pk#=1{x{)ScSIK68o#>Y5RvKIA ziB4B4Z9=Mfd8>)M)ei4=QB}F`%U-Cfo3y-=yg!b2JfDZ5)Ls+4{&h#fZ6l$sm@!ee z@nVFyrX9X9RUI*AgGbNb5|U~cR4HqrU)sbSTGm~-d&M0gZYJ)CF^#xZ$RfSxY3XrK zzwDx0$q4RSsyCw#tZP2FSi|N|yeGfwZ$w@iQ>S;Myrr%3M24=>A-Gv17L7Yn!xjMD z=O>lVyjSgrM;hj^Sz%T z09@;Jny4C_KH&`JW5@B7D`Dp8;<(-tWH}zyM`oCe{b{3)KcvPU%`YwI7{&&v4CfhK zIM{KJ;UJ(W2egpSG{!M`&OS!HC0pxUk=xU#D4A)xel2IfrU@lKpQQZ4`~fHa ziQ`VuI1%rR!D)J*N}}KloTV9qbMO(3dl5diAiT07c*MPwA(RL;;b22}Z9%w5Cyp^n z+R(Xl1Uf%j!06wBBhdNDf{@a2VmhC|<-+RxYyqRLgr&mj{9-{!>6BwS%W#Fjk_PxJ zlYCHio8-S*Kp9+xYt%3aQZ++5xOl%=kWzXs(HnyrjU~7apVQMN-5A`UzO2BP@%oMb E0Ryr?y#N3J diff --git a/target/classes/com/gameplatform/server/service/link/LinkGenerationService.class b/target/classes/com/gameplatform/server/service/link/LinkGenerationService.class new file mode 100644 index 0000000000000000000000000000000000000000..d14f52635fae58e7fe34cf6f2c1df1ca81ee8b94 GIT binary patch literal 9446 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