This commit is contained in:
root
2025-12-07 01:59:06 +05:00
parent 0d1cfbfeaf
commit 1ff6b611fb
5 changed files with 637 additions and 195 deletions
+396
View File
@@ -0,0 +1,396 @@
# Social Media Credentials API - Frontend Guide
## Обзор изменений
API для управления credentials социальных сетей был обновлен для поддержки разных форматов данных в зависимости от платформы. Поле `credentials` теперь может принимать как простую строку (токен), так и JSON объект для платформ, требующих несколько параметров.
## Базовый URL
```
http://your-server:port/api/social-media/credentials
```
## Аутентификация
Все endpoints требуют JWT токен в заголовке `Authorization`:
```
Authorization: Bearer <your-jwt-token>
```
## Изменения в API
### Поле `credentials` теперь поддерживает разные типы
**До изменений:**
- `credentials` был только `String` (токен)
**После изменений:**
- `credentials` может быть `String` (для простых токенов) или `Object` (для сложных структур)
### Поддерживаемые форматы
#### 1. Простой токен (String) - для Facebook, LinkedIn
```json
{
"platform": "facebook",
"credentials": "EAABwzLix..."
}
```
#### 2. JSON объект (Object) - для Telegram и других платформ с несколькими параметрами
```json
{
"platform": "telegram",
"credentials": {
"botToken": "123456789:ABCdefGHIjklMNOpqrsTUVwxyz",
"chatId": "-1001234567890"
}
}
```
## Endpoints
### 1. Сохранение/обновление credentials
**Endpoint:** `POST /api/social-media/credentials`
**Headers:**
```
Authorization: Bearer <token>
Content-Type: application/json
```
**Request Body для простого токена (Facebook/LinkedIn):**
```json
{
"platform": "facebook",
"credentials": "EAABwzLix..."
}
```
**Request Body для JSON объекта (Telegram):**
```json
{
"platform": "telegram",
"credentials": {
"botToken": "123456789:ABCdefGHIjklMNOpqrsTUVwxyz",
"chatId": "-1001234567890"
}
}
```
**Response 200 OK:**
```json
{
"success": true,
"message": "Credentials успешно сохранены для платформы telegram",
"data": {
"platform": "telegram",
"hasCredentials": true,
"createdAt": "2024-01-15T10:30:00",
"updatedAt": "2024-01-15T10:30:00"
}
}
```
**Примеры использования (JavaScript):**
```javascript
// Сохранение простого токена (Facebook/LinkedIn)
const saveFacebookCredentials = async (accessToken) => {
const response = await fetch('/api/social-media/credentials', {
method: 'POST',
headers: {
Authorization: `Bearer ${jwtToken}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
platform: 'facebook',
credentials: accessToken, // Простая строка
}),
});
const data = await response.json();
return data;
};
// Сохранение JSON объекта (Telegram)
const saveTelegramCredentials = async (botToken, chatId) => {
const response = await fetch('/api/social-media/credentials', {
method: 'POST',
headers: {
Authorization: `Bearer ${jwtToken}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
platform: 'telegram',
credentials: {
// JSON объект
botToken: botToken,
chatId: chatId,
},
}),
});
const data = await response.json();
return data;
};
// Использование
await saveFacebookCredentials('EAABwzLix...');
await saveTelegramCredentials('123456789:ABC...', '-1001234567890');
```
### 2. Получение информации о credentials
**Endpoint:** `GET /api/social-media/credentials/{platform}`
**Headers:**
```
Authorization: Bearer <token>
```
**Path Parameters:**
- `platform` (string) - Название платформы
**Response 200 OK:**
```json
{
"success": true,
"message": "Операция выполнена успешно",
"data": {
"platform": "telegram",
"hasCredentials": true
}
}
```
### 3. Получение списка всех credentials
**Endpoint:** `GET /api/social-media/credentials`
**Headers:**
```
Authorization: Bearer <token>
```
**Response 200 OK:**
```json
{
"success": true,
"message": "Операция выполнена успешно",
"data": [
{
"platform": "facebook",
"hasCredentials": true,
"createdAt": "2024-01-15T10:30:00",
"updatedAt": "2024-01-15T10:30:00"
},
{
"platform": "telegram",
"hasCredentials": true,
"createdAt": "2024-01-15T11:00:00",
"updatedAt": "2024-01-15T11:00:00"
}
]
}
```
### 4. Удаление credentials
**Endpoint:** `DELETE /api/social-media/credentials/{platform}`
**Headers:**
```
Authorization: Bearer <token>
```
**Path Parameters:**
- `platform` (string) - Название платформы
**Response 200 OK:**
```json
{
"success": true,
"message": "Credentials для платформы telegram успешно удалены",
"data": null
}
```
## Форматы credentials по платформам
### Facebook
```json
{
"platform": "facebook",
"credentials": "EAABwzLix..." // Access Token
}
```
### LinkedIn
```json
{
"platform": "linkedin",
"credentials": "AQV..." // Access Token
}
```
### Telegram
```json
{
"platform": "telegram",
"credentials": {
"botToken": "123456789:ABCdefGHIjklMNOpqrsTUVwxyz",
"chatId": "-1001234567890"
}
}
```
**Примечание для Telegram:**
- `botToken` - токен бота, полученный от @BotFather
- `chatId` - ID чата/канала (может быть отрицательным для групп и каналов)
- Формат: `-1001234567890` для супергрупп и каналов
## Обработка ошибок
### 400 Bad Request - Ошибка валидации
```json
{
"success": false,
"message": "Ошибка валидации",
"error": {
"code": "VALIDATION_ERROR",
"message": "Platform is required",
"details": {
"platform": "Platform is required"
}
}
}
```
### 401 Unauthorized
```json
{
"success": false,
"message": "Не авторизован",
"error": {
"code": "UNAUTHORIZED",
"message": "Требуется аутентификация. Пожалуйста, предоставьте валидный JWT токен."
}
}
```
### 500 Internal Server Error
```json
{
"success": false,
"message": "Внутренняя ошибка сервера",
"error": {
"code": "INTERNAL_SERVER_ERROR",
"message": "Произошла ошибка при сохранении credentials"
}
}
```
## Миграция с старого API
Если вы использовали старый API, где `credentials` был только строкой, изменения минимальны:
**Старый код:**
```javascript
body: JSON.stringify({
platform: 'facebook',
credentials: 'EAABwzLix...',
});
```
**Новый код (без изменений для простых токенов):**
```javascript
// Работает как раньше
body: JSON.stringify({
platform: 'facebook',
credentials: 'EAABwzLix...', // String по-прежнему поддерживается
});
```
**Для Telegram (новый формат):**
```javascript
body: JSON.stringify({
platform: 'telegram',
credentials: {
// Теперь можно передавать объект
botToken: '...',
chatId: '...',
},
});
```
## Важные замечания
1. **Обратная совместимость**: API полностью обратно совместим. Старый формат (String) продолжает работать.
2. **Автоматическая конвертация**: Если вы передаете объект, он автоматически сериализуется в JSON строку перед сохранением.
3. **Безопасность**: Все credentials автоматически шифруются перед сохранением в базе данных.
4. **Валидация**: Поле `credentials` обязательно (`@NotNull`), но может быть как строкой, так и объектом.
## Примеры для TypeScript
```typescript
interface SimpleCredentials {
platform: string;
credentials: string; // Для Facebook, LinkedIn
}
interface TelegramCredentials {
platform: 'telegram';
credentials: {
botToken: string;
chatId: string;
};
}
type CredentialsRequest = SimpleCredentials | TelegramCredentials;
// Использование
const saveCredentials = async (request: CredentialsRequest) => {
const response = await fetch('/api/social-media/credentials', {
method: 'POST',
headers: {
Authorization: `Bearer ${jwtToken}`,
'Content-Type': 'application/json',
},
body: JSON.stringify(request),
});
return response.json();
};
```
@@ -1,9 +1,12 @@
package kz.konturai.parser.controller;
import com.fasterxml.jackson.databind.ObjectMapper;
import kz.konturai.parser.dto.*;
import kz.konturai.parser.model.SocialMediaCredentials;
import kz.konturai.parser.service.JwtService;
import kz.konturai.parser.service.SocialMediaCredentialsService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.MethodArgumentNotValidException;
@@ -19,193 +22,219 @@ import java.util.stream.Collectors;
@RequestMapping("/api/social-media/credentials")
public class SocialMediaCredentialsController {
private final SocialMediaCredentialsService credentialsService;
private final JwtService jwtService;
private static final Logger logger = LoggerFactory.getLogger(SocialMediaCredentialsController.class);
public SocialMediaCredentialsController(
SocialMediaCredentialsService credentialsService,
JwtService jwtService) {
this.credentialsService = credentialsService;
this.jwtService = jwtService;
}
private final SocialMediaCredentialsService credentialsService;
private final JwtService jwtService;
private final ObjectMapper objectMapper;
private String extractUserIdFromHeader(String authHeader) {
if (authHeader == null || authHeader.isEmpty()) {
return null;
}
return jwtService.extractUserIdFromHeader(authHeader);
}
private ResponseEntity<?> unauthorizedResponse() {
ErrorResponse error = new ErrorResponse(
"UNAUTHORIZED",
"Требуется аутентификация. Пожалуйста, предоставьте валидный JWT токен.");
return ResponseEntity.status(HttpStatus.UNAUTHORIZED)
.body(ApiResponse.error("Не авторизован", error));
}
/**
* Сохранение или обновление credentials для платформы
* POST /api/social-media/credentials
*/
@PostMapping
public ResponseEntity<?> saveCredentials(
@RequestHeader(value = "Authorization", required = false) String authHeader,
@Valid @RequestBody SocialMediaCredentialsRequest request) {
String userId = extractUserIdFromHeader(authHeader);
if (userId == null) {
return unauthorizedResponse();
public SocialMediaCredentialsController(
SocialMediaCredentialsService credentialsService,
JwtService jwtService) {
this.credentialsService = credentialsService;
this.jwtService = jwtService;
this.objectMapper = new ObjectMapper();
}
try {
SocialMediaCredentials credentials = credentialsService.saveCredentials(
userId,
request.getPlatform(),
request.getCredentials()
);
SocialMediaCredentialsResponse response = new SocialMediaCredentialsResponse(
credentials.getPlatform(),
true,
credentials.getCreatedAt(),
credentials.getUpdatedAt()
);
return ResponseEntity.ok(ApiResponse.success(
"Credentials успешно сохранены для платформы " + request.getPlatform(),
response));
} catch (IllegalArgumentException e) {
ErrorResponse error = new ErrorResponse("VALIDATION_ERROR", e.getMessage());
return ResponseEntity.badRequest()
.body(ApiResponse.error("Ошибка валидации", error));
} catch (Exception e) {
ErrorResponse error = new ErrorResponse(
"INTERNAL_SERVER_ERROR",
"Произошла ошибка при сохранении credentials");
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body(ApiResponse.error("Внутренняя ошибка сервера", error));
}
}
/**
* Получение информации о credentials для платформы
* GET /api/social-media/credentials/{platform}
*/
@GetMapping("/{platform}")
public ResponseEntity<?> getCredentials(
@RequestHeader(value = "Authorization", required = false) String authHeader,
@PathVariable String platform) {
String userId = extractUserIdFromHeader(authHeader);
if (userId == null) {
return unauthorizedResponse();
private String extractUserIdFromHeader(String authHeader) {
if (authHeader == null || authHeader.isEmpty()) {
return null;
}
return jwtService.extractUserIdFromHeader(authHeader);
}
boolean hasCredentials = credentialsService.hasCredentials(userId, platform);
SocialMediaCredentialsResponse response = new SocialMediaCredentialsResponse(
platform,
hasCredentials
);
return ResponseEntity.ok(ApiResponse.success(response));
}
/**
* Получение списка всех платформ с credentials
* GET /api/social-media/credentials
*/
@GetMapping
public ResponseEntity<?> getAllCredentials(
@RequestHeader(value = "Authorization", required = false) String authHeader) {
String userId = extractUserIdFromHeader(authHeader);
if (userId == null) {
return unauthorizedResponse();
}
List<SocialMediaCredentials> credentialsList = credentialsService.getUserCredentials(userId);
List<SocialMediaCredentialsResponse> responseList = credentialsList.stream()
.map(cred -> new SocialMediaCredentialsResponse(
cred.getPlatform(),
true,
cred.getCreatedAt(),
cred.getUpdatedAt()
))
.collect(Collectors.toList());
return ResponseEntity.ok(ApiResponse.success(responseList));
}
/**
* Удаление credentials для платформы
* DELETE /api/social-media/credentials/{platform}
*/
@DeleteMapping("/{platform}")
public ResponseEntity<?> deleteCredentials(
@RequestHeader(value = "Authorization", required = false) String authHeader,
@PathVariable String platform) {
String userId = extractUserIdFromHeader(authHeader);
if (userId == null) {
return unauthorizedResponse();
}
try {
if (!credentialsService.hasCredentials(userId, platform)) {
private ResponseEntity<?> unauthorizedResponse() {
ErrorResponse error = new ErrorResponse(
"NOT_FOUND",
"Credentials для платформы " + platform + " не найдены");
return ResponseEntity.status(HttpStatus.NOT_FOUND)
.body(ApiResponse.error("Credentials не найдены", error));
}
credentialsService.deleteCredentials(userId, platform);
return ResponseEntity.ok(ApiResponse.success(
"Credentials для платформы " + platform + " успешно удалены",
null));
} catch (IllegalArgumentException e) {
ErrorResponse error = new ErrorResponse("VALIDATION_ERROR", e.getMessage());
return ResponseEntity.badRequest()
.body(ApiResponse.error("Ошибка валидации", error));
} catch (Exception e) {
ErrorResponse error = new ErrorResponse(
"INTERNAL_SERVER_ERROR",
"Произошла ошибка при удалении credentials");
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body(ApiResponse.error("Внутренняя ошибка сервера", error));
"UNAUTHORIZED",
"Требуется аутентификация. Пожалуйста, предоставьте валидный JWT токен.");
return ResponseEntity.status(HttpStatus.UNAUTHORIZED)
.body(ApiResponse.error("Не авторизован", error));
}
}
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<ApiResponse<ErrorResponse>> handleValidationException(
MethodArgumentNotValidException ex) {
/**
* Сохранение или обновление credentials для платформы
* POST /api/social-media/credentials
*/
@PostMapping
public ResponseEntity<?> saveCredentials(
@RequestHeader(value = "Authorization", required = false) String authHeader,
@Valid @RequestBody SocialMediaCredentialsRequest request) {
Map<String, String> details = new HashMap<>();
ex.getBindingResult().getFieldErrors().forEach(error -> {
details.put(error.getField(), error.getDefaultMessage());
});
String userId = extractUserIdFromHeader(authHeader);
if (userId == null) {
return unauthorizedResponse();
}
ErrorResponse errorResponse = new ErrorResponse(
"VALIDATION_ERROR",
"Ошибка валидации входных данных",
details);
try {
// Конвертируем credentials в строку: если это String - используем как есть,
// если Object - сериализуем в JSON
String credentialsString = convertCredentialsToString(request.getCredentials());
return ResponseEntity.badRequest()
.body(ApiResponse.error("Ошибка валидации", errorResponse));
}
SocialMediaCredentials credentials = credentialsService.saveCredentials(
userId,
request.getPlatform(),
credentialsString);
@ExceptionHandler(Exception.class)
public ResponseEntity<ApiResponse<ErrorResponse>> handleGenericException(Exception e) {
ErrorResponse errorResponse = new ErrorResponse(
"INTERNAL_SERVER_ERROR",
"Произошла внутренняя ошибка сервера. Попробуйте позже.");
SocialMediaCredentialsResponse response = new SocialMediaCredentialsResponse(
credentials.getPlatform(),
true,
credentials.getCreatedAt(),
credentials.getUpdatedAt());
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body(ApiResponse.error("Внутренняя ошибка сервера", errorResponse));
}
return ResponseEntity.ok(ApiResponse.success(
"Credentials успешно сохранены для платформы " + request.getPlatform(),
response));
} catch (IllegalArgumentException e) {
ErrorResponse error = new ErrorResponse("VALIDATION_ERROR", e.getMessage());
return ResponseEntity.badRequest()
.body(ApiResponse.error("Ошибка валидации", error));
} catch (Exception e) {
ErrorResponse error = new ErrorResponse(
"INTERNAL_SERVER_ERROR",
"Произошла ошибка при сохранении credentials");
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body(ApiResponse.error("Внутренняя ошибка сервера", error));
}
}
/**
* Получение информации о credentials для платформы
* GET /api/social-media/credentials/{platform}
*/
@GetMapping("/{platform}")
public ResponseEntity<?> getCredentials(
@RequestHeader(value = "Authorization", required = false) String authHeader,
@PathVariable String platform) {
String userId = extractUserIdFromHeader(authHeader);
if (userId == null) {
return unauthorizedResponse();
}
boolean hasCredentials = credentialsService.hasCredentials(userId, platform);
SocialMediaCredentialsResponse response = new SocialMediaCredentialsResponse(
platform,
hasCredentials);
return ResponseEntity.ok(ApiResponse.success(response));
}
/**
* Получение списка всех платформ с credentials
* GET /api/social-media/credentials
*/
@GetMapping
public ResponseEntity<?> getAllCredentials(
@RequestHeader(value = "Authorization", required = false) String authHeader) {
String userId = extractUserIdFromHeader(authHeader);
if (userId == null) {
return unauthorizedResponse();
}
List<SocialMediaCredentials> credentialsList = credentialsService.getUserCredentials(userId);
List<SocialMediaCredentialsResponse> responseList = credentialsList.stream()
.map(cred -> new SocialMediaCredentialsResponse(
cred.getPlatform(),
true,
cred.getCreatedAt(),
cred.getUpdatedAt()))
.collect(Collectors.toList());
return ResponseEntity.ok(ApiResponse.success(responseList));
}
/**
* Удаление credentials для платформы
* DELETE /api/social-media/credentials/{platform}
*/
@DeleteMapping("/{platform}")
public ResponseEntity<?> deleteCredentials(
@RequestHeader(value = "Authorization", required = false) String authHeader,
@PathVariable String platform) {
String userId = extractUserIdFromHeader(authHeader);
if (userId == null) {
return unauthorizedResponse();
}
try {
if (!credentialsService.hasCredentials(userId, platform)) {
ErrorResponse error = new ErrorResponse(
"NOT_FOUND",
"Credentials для платформы " + platform + " не найдены");
return ResponseEntity.status(HttpStatus.NOT_FOUND)
.body(ApiResponse.error("Credentials не найдены", error));
}
credentialsService.deleteCredentials(userId, platform);
return ResponseEntity.ok(ApiResponse.success(
"Credentials для платформы " + platform + " успешно удалены",
null));
} catch (IllegalArgumentException e) {
ErrorResponse error = new ErrorResponse("VALIDATION_ERROR", e.getMessage());
return ResponseEntity.badRequest()
.body(ApiResponse.error("Ошибка валидации", error));
} catch (Exception e) {
ErrorResponse error = new ErrorResponse(
"INTERNAL_SERVER_ERROR",
"Произошла ошибка при удалении credentials");
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body(ApiResponse.error("Внутренняя ошибка сервера", error));
}
}
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<ApiResponse<ErrorResponse>> handleValidationException(
MethodArgumentNotValidException ex) {
Map<String, String> details = new HashMap<>();
ex.getBindingResult().getFieldErrors().forEach(error -> {
details.put(error.getField(), error.getDefaultMessage());
});
ErrorResponse errorResponse = new ErrorResponse(
"VALIDATION_ERROR",
"Ошибка валидации входных данных",
details);
return ResponseEntity.badRequest()
.body(ApiResponse.error("Ошибка валидации", errorResponse));
}
@ExceptionHandler(Exception.class)
public ResponseEntity<ApiResponse<ErrorResponse>> handleGenericException(Exception e) {
ErrorResponse errorResponse = new ErrorResponse(
"INTERNAL_SERVER_ERROR",
"Произошла внутренняя ошибка сервера. Попробуйте позже.");
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body(ApiResponse.error("Внутренняя ошибка сервера", errorResponse));
}
/**
* Конвертирует credentials (Object или String) в строку для сохранения
* Если это String - возвращает как есть
* Если это Object - сериализует в JSON строку
*/
private String convertCredentialsToString(Object credentials) {
if (credentials == null) {
throw new IllegalArgumentException("Credentials cannot be null");
}
if (credentials instanceof String) {
return (String) credentials;
}
try {
// Сериализуем объект в JSON строку
return objectMapper.writeValueAsString(credentials);
} catch (Exception e) {
logger.error("Failed to serialize credentials to JSON", e);
throw new IllegalArgumentException("Failed to serialize credentials: " + e.getMessage(), e);
}
}
}
@@ -1,19 +1,22 @@
package kz.konturai.parser.dto;
import com.fasterxml.jackson.annotation.JsonProperty;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
public class SocialMediaCredentialsRequest {
@NotBlank(message = "Platform is required")
private String platform;
@NotBlank(message = "Credentials are required")
private String credentials;
@NotNull(message = "Credentials are required")
@JsonProperty("credentials")
private Object credentials; // Может быть String (токен) или Object (JSON объект для Telegram и др.)
public SocialMediaCredentialsRequest() {
}
public SocialMediaCredentialsRequest(String platform, String credentials) {
public SocialMediaCredentialsRequest(String platform, Object credentials) {
this.platform = platform;
this.credentials = credentials;
}
@@ -26,12 +29,11 @@ public class SocialMediaCredentialsRequest {
this.platform = platform;
}
public String getCredentials() {
public Object getCredentials() {
return credentials;
}
public void setCredentials(String credentials) {
public void setCredentials(Object credentials) {
this.credentials = credentials;
}
}
@@ -19,7 +19,7 @@ public class SocialMediaCredentials {
private String platform; // "facebook", "instagram", etc.
@Field("encrypted_credentials")
private String encryptedCredentials;
private Object encryptedCredentials;
@Field("created_at")
private LocalDateTime createdAt;
@@ -32,7 +32,7 @@ public class SocialMediaCredentials {
this.updatedAt = LocalDateTime.now();
}
public SocialMediaCredentials(String userId, String platform, String encryptedCredentials) {
public SocialMediaCredentials(String userId, String platform, Object encryptedCredentials) {
this();
this.userId = userId;
this.platform = platform;
@@ -63,11 +63,11 @@ public class SocialMediaCredentials {
this.platform = platform;
}
public String getEncryptedCredentials() {
public Object getEncryptedCredentials() {
return encryptedCredentials;
}
public void setEncryptedCredentials(String encryptedCredentials) {
public void setEncryptedCredentials(Object encryptedCredentials) {
this.encryptedCredentials = encryptedCredentials;
this.updatedAt = LocalDateTime.now();
}
@@ -88,4 +88,3 @@ public class SocialMediaCredentials {
this.updatedAt = updatedAt;
}
}
@@ -27,9 +27,11 @@ public class SocialMediaCredentialsService {
/**
* Сохраняет или обновляет credentials пользователя для платформы
*
* @param userId ID пользователя
* @param platform Платформа (facebook, instagram, etc.)
* @param credentials Открытые credentials (будут зашифрованы)
* @param userId ID пользователя
* @param platform Платформа (facebook, instagram, telegram, etc.)
* @param credentials Открытые credentials (могут быть String для токена или
* JSON строка для объектов, например для Telegram:
* {"botToken": "...", "chatId": "..."})
* @return Сохраненные credentials
*/
public SocialMediaCredentials saveCredentials(String userId, String platform, String credentials) {
@@ -39,7 +41,7 @@ public class SocialMediaCredentialsService {
// Проверяем существующие credentials
Optional<SocialMediaCredentials> existing = repository.findByUserIdAndPlatform(userId, platform);
SocialMediaCredentials credentialsEntity;
if (existing.isPresent()) {
credentialsEntity = existing.get();
@@ -61,7 +63,7 @@ public class SocialMediaCredentialsService {
/**
* Получает и расшифровывает credentials пользователя для платформы
*
* @param userId ID пользователя
* @param userId ID пользователя
* @param platform Платформа
* @return Расшифрованные credentials или null если не найдены
*/
@@ -80,7 +82,22 @@ public class SocialMediaCredentialsService {
try {
SocialMediaCredentials credentialsEntity = optCredentials.get();
return encryptionService.decrypt(credentialsEntity.getEncryptedCredentials());
Object encryptedCreds = credentialsEntity.getEncryptedCredentials();
// Если это String (старый формат или зашифрованная строка), расшифровываем
if (encryptedCreds instanceof String) {
return encryptionService.decrypt((String) encryptedCreds);
}
// Если это Object (например, Map из MongoDB), сериализуем в JSON, затем
// расшифровываем
// Но обычно зашифрованные данные хранятся как String
if (encryptedCreds != null) {
String encryptedString = encryptedCreds.toString();
return encryptionService.decrypt(encryptedString);
}
return null;
} catch (Exception e) {
logger.error("Failed to decrypt credentials for user {} and platform {}", userId, platform, e);
throw new RuntimeException("Failed to decrypt credentials", e);
@@ -90,7 +107,7 @@ public class SocialMediaCredentialsService {
/**
* Проверяет наличие credentials для пользователя и платформы
*
* @param userId ID пользователя
* @param userId ID пользователя
* @param platform Платформа
* @return true если credentials существуют
*/
@@ -105,7 +122,7 @@ public class SocialMediaCredentialsService {
/**
* Удаляет credentials пользователя для платформы
*
* @param userId ID пользователя
* @param userId ID пользователя
* @param platform Платформа
*/
public void deleteCredentials(String userId, String platform) {
@@ -147,4 +164,3 @@ public class SocialMediaCredentialsService {
return repository.findByUserId(userId);
}
}