itd-sdk-js 1.0.9 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/API_REFERENCE.md CHANGED
@@ -2,6 +2,69 @@
2
2
 
3
3
  Техническое руководство по методам и настройке библиотеки для работы с API сайта `итд.com`.
4
4
 
5
+ ## Подтверждённые эндпоинты
6
+
7
+ | Метод | Эндпоинт | Описание |
8
+ |-------|----------|----------|
9
+ | GET | `/api/users/{username}` | Профиль → `{ id, username, displayName, avatar, banner, bio, verified, pinnedPostId, wallClosed, followersCount, followingCount, postsCount, isFollowing, isFollowedBy, createdAt }` |
10
+ | GET | `/api/users/{username}/followers?page=1&limit=30` | Подписчики → `{ data: { users: [], pagination: { page, limit, total, hasMore } } }` |
11
+ | GET | `/api/users/{username}/following?page=1&limit=30` | Подписки → `{ data: { users: [], pagination } }` |
12
+ | GET | `/api/posts/user/{username}?limit=20&sort=new` | Посты пользователя → `{ data: { posts: [], pagination: { limit, nextCursor, hasMore } } }` |
13
+ | GET | `/api/posts/user/{username}/liked?limit=20` | Лайкнутые посты → `{ data: { posts: [], pagination } }` |
14
+ | GET | `/api/hashtags/{name}/posts?limit=20` | Посты по хэштегу → `{ data: { hashtag: {}, posts: [], pagination } }` |
15
+ | GET | `/api/hashtags/trending?limit=10` | Трендовые хэштеги → `{ data: { hashtags: [{ id, name, postsCount }] } }` |
16
+ | GET | `/api/users/suggestions/who-to-follow` | Рекомендации → `{ users: [] }` |
17
+ | GET | `/api/users/stats/top-clans` | Топ кланов → `{ clans: [{ avatar, memberCount }] }` |
18
+ | POST | `/api/posts` | Создать пост. `{ content, wallRecipientId?, attachmentIds? }` → `{ id, content, author, ... }` |
19
+ | PUT | `/api/posts/{id}` | Редактировать пост. `{ content }` → `{ id, content, updatedAt }` |
20
+ | DELETE | `/api/posts/{id}` | Удалить пост (пустой ответ) |
21
+ | POST | `/api/posts/{id}/restore` | Восстановить пост (пустой ответ) |
22
+ | POST | `/api/posts/{id}/repost` | Репост. `{ content? }` (комментарий опционально). **attachmentIds игнорируется** — вложения в репост не поддерживаются. |
23
+ | POST | `/api/posts/{id}/like` | Лайк → `{ liked: true, likesCount }` |
24
+ | DELETE | `/api/posts/{id}/like` | Снять лайк → `{ liked: false, likesCount }` |
25
+ | POST | `/api/posts/{id}/pin` | Закрепить пост → `{ success: true, pinnedPostId }` |
26
+ | DELETE | `/api/posts/{id}/pin` | Открепить пост → `{ success: true, pinnedPostId: null }` |
27
+ | POST | `/api/posts/{id}/view` | Отметить пост как просмотренный |
28
+ | GET | `/api/posts/user/{username}/wall` | Посты на стене пользователя → `{ data: { posts: [], pagination } }` |
29
+ | POST | `/api/comments/{id}/restore` | Восстановить удалённый комментарий |
30
+ | POST | `/api/v1/auth/change-password` | Смена пароля. `{ oldPassword, newPassword }`. Требует cookies. |
31
+ | GET | `/api/files/{id}` | Информация о файле |
32
+ | DELETE | `/api/files/{id}` | Удалить файл |
33
+ | GET | `/api/verification/status` | Статус верификации |
34
+ | POST | `/api/verification/submit` | Подать заявку на верификацию. `{ videoUrl }` |
35
+ | GET | `/api/platform/status` | Статус платформы |
36
+ | POST | `/api/files/upload` | Загрузка файла (изображения, audio/ogg). → 201, `{ id, url, filename, mimeType, size }` |
37
+ | PUT | `/api/users/me` | Обновить профиль (bio, displayName, username, bannerId) |
38
+ | POST | `/api/reports` | Рекорт. `{ targetType, targetId, reason, description? }` → `{ data: { id, createdAt } }`. reason: `spam`, `violence`, `hate`, `adult`, `fraud`, `other` |
39
+ | GET | `/api/notifications/?offset=0&limit=20` | Список уведомлений → `{ notifications: [], hasMore }` |
40
+ | POST | `/api/notifications/read-batch` | Отметить несколько прочитанными → `{ success: true, count }` |
41
+ | POST | `/api/notifications/read-all` | Отметить все прочитанными → `{ success: true }` |
42
+ | GET | `/api/users/me/privacy` | Настройки приватности → `{ isPrivate, wallClosed }` |
43
+ | PUT | `/api/users/me/privacy` | Обновить приватность |
44
+ | POST | `/api/v1/auth/refresh` | Обновить токен → `{ accessToken }` |
45
+ | POST | `/api/v1/auth/logout` | Выход → 204 |
46
+ | GET | `/api/posts/{id}` | Один пост |
47
+ | GET | `/api/posts/{postId}/comments?limit&sort` | Комментарии к посту → `{ data: { comments: [], total, hasMore, nextCursor } }`. sort: `newest`, `oldest`, `popular` |
48
+ | POST | `/api/posts/{postId}/comments` | Добавить комментарий. `{ content?, attachmentIds? }` — голосовые: content пустой, attachmentIds с id из uploadFile (audio/ogg) |
49
+ | POST | `/api/comments/{id}/replies` | Ответ на комментарий. `{ content, replyToUserId }` |
50
+ | GET | `/api/comments/{id}/replies?page&limit&sort` | Ответы на комментарий (пагинация по page) |
51
+ | POST | `/api/reports` | targetType: `post`, `comment`, `user`. 400 при повторном репорте: «Вы уже отправляли жалобу» |
52
+ | DELETE | `/api/comments/{id}` | Удалить комментарий (пустой ответ). На своей стене можно удалять любые. |
53
+ | POST/DELETE | `/api/comments/{id}/like` | Лайк/снять лайк на комментарий или реплай → `{ liked, likesCount }` |
54
+ | POST | `/api/users/{username}/follow` | Подписаться → `{ following: true, followersCount }` |
55
+ | DELETE | `/api/users/{username}/follow` | Отписаться → `{ following: false, followersCount }` |
56
+
57
+ ### Эндпоинты без подтверждения
58
+
59
+ | Метод | Эндпоинт | Используется в |
60
+ |-------|----------|----------------|
61
+ | GET | `/api/posts?tab=popular` / `tab=following` | `getFeedPopular`, `getFeedFollowing` — в веб-интерфейсе нет переключения |
62
+ | POST | `/api/notifications/{id}/read` | `markNotificationAsRead` |
63
+ | GET | `/api/notifications/count` | `getNotificationCount`, `hasUnreadNotifications` |
64
+ | GET | `/api/search/?q=&userLimit=&hashtagLimit=` | `search`, `searchUsers`, `searchHashtags` |
65
+
66
+ Если какой‑то метод возвращает ошибку — проверь эндпоинт в DevTools.
67
+
5
68
  ## Структура SDK
6
69
 
7
70
  | Файл | Назначение |
@@ -14,7 +77,8 @@
14
77
  | `users.js` | Пользователи: getMyProfile, getUserProfile, followUser, getTopClans и др. |
15
78
  | `notifications.js` | Уведомления |
16
79
  | `hashtags.js` | Хэштеги |
17
- | `files.js` | Загрузка файлов |
80
+ | `files.js` | Загрузка, получение, удаление файлов |
81
+ | `verification.js` | Верификация: getStatus, submit |
18
82
  | `search.js` | Поиск |
19
83
  | `reports.js` | Жалобы |
20
84
 
@@ -177,13 +241,18 @@ const post = await client.createPost('Текст поста', 'image.jpg');
177
241
 
178
242
  ### Прочие методы постов
179
243
 
180
- - `getFeedPopular(limit, cursor)` — лента популярных постов. Возвращает `{ posts: [], pagination: {} }`.
181
- - `getFeedFollowing(limit, cursor)` — лента подписок. Требует авторизацию. Возвращает `{ posts: [], pagination: {} }`.
244
+ - `getFeedPopular(limit, cursor)` — лента популярных постов. ⚠️ GET `/api/posts?tab=popular` **не подтверждён** веб-интерфейсе нет переключения). Тула для теста: `tools/test-feed-tabs.js`.
245
+ - `getFeedFollowing(limit, cursor)` — лента подписок. ⚠️ GET `/api/posts?tab=following` **не подтверждён**. Требует авторизацию.
182
246
  - `getPostsList(username?, limit?)` — упрощенный метод, возвращает только массив постов (без pagination).
183
- - `editPost(postId, newContent)` — редактирование текста. Возвращает обновленный объект поста.
184
- - `deletePost(postId)` — удаление поста. Возвращает `boolean`.
185
- - `pinPost(postId)` — закрепление записи. Возвращает `boolean`.
186
- - `repost(postId, comment?)` — репост (нельзя репостнуть себя). Возвращает объект репоста.
247
+ - `editPost(postId, newContent)` — редактирование текста. PUT `/api/posts/{id}`. `{ content }` → `{ id, content, updatedAt }`.
248
+ - `viewPost(postId)` — отметить пост как просмотренный. POST `/api/posts/{id}/view`.
249
+ - `getWallByUser(username, limit, cursor)` — посты на стене пользователя. GET `/api/posts/user/{username}/wall`.
250
+ - `deletePost(postId)` — удаление поста. DELETE `/api/posts/{id}`. Возвращает `boolean`.
251
+ - `restorePost(postId)` — восстановление удалённого поста. POST `/api/posts/{id}/restore`.
252
+ - `getLikedPosts(username, limit, cursor)` — лайкнутые посты пользователя. GET `/api/posts/user/{username}/liked` → `{ posts: [], pagination }`.
253
+ - `pinPost(postId)` — закрепить пост. POST `/api/posts/{id}/pin` → `{ success: true, pinnedPostId }`.
254
+ - `unpinPost(postId)` — открепить пост. DELETE `/api/posts/{id}/pin` → `{ success: true, pinnedPostId: null }`.
255
+ - `repost(postId, comment?)` — репост. POST `/api/posts/{id}/repost`. `{ content? }` (комментарий опционально). **attachmentIds не поддерживается** — API игнорирует вложения при репосте.
187
256
  - `likePost(postId)` **/** `unlikePost(postId)` — управление лайками. Возвращают `{ liked: boolean, likesCount: number }`.
188
257
 
189
258
  ---
@@ -192,14 +261,22 @@ const post = await client.createPost('Текст поста', 'image.jpg');
192
261
 
193
262
  ### getComments(postId, limit, sort)
194
263
 
195
- Получает дерево комментариев к посту.
264
+ Получает дерево комментариев к посту. GET `/api/posts/{postId}/comments?limit&sort`.
196
265
 
197
266
  - **Параметры**: `postId`, `limit` (по умолчанию 20, в запросе ограничивается 1–100), `sort` — в SDK можно передавать `"popular"`, `"new"`, `"old"`; в API уходит `popular`, `newest`, `oldest` соответственно.
198
267
  - **Ответ API:** `{ data: { comments: [], total, hasMore, nextCursor } }`. Комментарии могут содержать вложенные `replies`, у ответов — поле `replyTo`.
268
+ - **Отдельный эндпоинт для ответов:** GET `/api/comments/{id}/replies?page=1&limit=50&sort=oldest` — пагинация по `page`, не по cursor. В SDK нет отдельного метода `getReplies`; ответы приходят внутри `getComments`.
269
+
270
+ ### addComment(postId, text, replyToCommentId?, attachmentIds?)
271
+
272
+ Добавляет новый комментарий. POST `/api/posts/{postId}/comments`. Payload: `{ content?, attachmentIds? }`.
199
273
 
200
- ### addComment(postId, text, replyToCommentId?)
274
+ - **Текст**: `content` — текст комментария.
275
+ - **Голосовое**: `content` пустой, `attachmentIds: [uploadedId]` — id из `uploadFile` (audio/ogg). Вложения в ответе имеют `type: "audio"`, `duration`, `mimeType: "audio/ogg"`.
201
276
 
202
- Добавляет новый комментарий или ответ на существующий (POST к посту: `/api/posts/:postId/comments`).
277
+ ### addVoiceComment(postId, audioPath, replyToCommentId?)
278
+
279
+ Добавляет голосовое сообщение. Загружает audio/ogg через `uploadFile` и создаёт комментарий с `attachmentIds`. Удобный метод поверх `addComment(postId, '', replyToCommentId, [uploadedId])`.
203
280
 
204
281
  ### replyToComment(commentId, content, replyToUserId)
205
282
 
@@ -215,8 +292,9 @@ const post = await client.createPost('Текст поста', 'image.jpg');
215
292
 
216
293
  ### Управление комментариями
217
294
 
218
- - `likeComment(commentId)` **/** `unlikeComment(commentId)` — лайки на комментарии.
219
- - `deleteComment(commentId)` — удаление комментария.
295
+ - `likeComment(commentId)` **/** `unlikeComment(commentId)` — лайки на комментарии/реплаи. POST/DELETE `/api/comments/{id}/like` → `{ liked, likesCount }`.
296
+ - `deleteComment(commentId)` — удаление комментария. DELETE `/api/comments/{id}` (пустой ответ). На своей стене можно удалять любые комментарии.
297
+ - `restoreComment(commentId)` — восстановление удалённого комментария. POST `/api/comments/{id}/restore`.
220
298
 
221
299
  ---
222
300
 
@@ -224,10 +302,12 @@ const post = await client.createPost('Текст поста', 'image.jpg');
224
302
 
225
303
  - `getMyProfile()` — данные текущего аккаунта (требует auth).
226
304
  - `getUserProfile(username)` — публичный профиль любого пользователя.
227
- - `updateProfile(bio, displayName?)` — изменение описания и имени.
305
+ - `updateProfile(bio?, displayName?, username?, bannerId?)` — обновление профиля. PUT `/api/users/me`. Поддерживает `bannerId` (ID из `uploadFile`).
306
+ - `getPrivacy()` — настройки приватности. GET `/api/users/me/privacy` → `{ isPrivate, wallClosed }`.
307
+ - `updatePrivacy({ isPrivate?, wallClosed? })` — обновление приватности. PUT `/api/users/me/privacy`.
228
308
  - `getFollowers(username, page, limit)` — список подписчиков.
229
309
  - `getFollowing(username, page, limit)` — список подписок.
230
- - `followUser(username)` **/** `unfollowUser(username)` — подписка/отписка.
310
+ - `followUser(username)` **/** `unfollowUser(username)` — подписка/отписка. POST/DELETE `/api/users/{username}/follow` → `{ following, followersCount }`.
231
311
  - `getUserClan(username)` — получение эмодзи-аватара пользователя.
232
312
 
233
313
  ## Методы API: Управление токенами
@@ -239,26 +319,36 @@ const post = await client.createPost('Текст поста', 'image.jpg');
239
319
 
240
320
  **Кастомные запросы:** `client.get(path)`, `client.post(path, data)`, `client.put(path, data)`, `client.patch(path, data)`, `client.delete(path)` — для произвольных эндпоинтов (baseURL уже подставлен).
241
321
 
322
+ - `changePassword(oldPassword, newPassword)` — смена пароля. POST `/api/v1/auth/change-password`. Требует cookies (refresh_token).
323
+ - `getVerificationStatus()` — статус верификации. GET `/api/verification/status`.
324
+ - `submitVerification(videoUrl)` — подать заявку на верификацию. POST `/api/verification/submit`. videoUrl — URL из `uploadFile`.
325
+ - `getPlatformStatus()` — статус платформы. GET `/api/platform/status`.
326
+ - `getFile(fileId)` — информация о файле. GET `/api/files/{id}`.
327
+ - `deleteFile(fileId)` — удалить файл. DELETE `/api/files/{id}`.
328
+
242
329
  **Рекомендация:** При множественных запросах с интервалами (более 10-15 минут) вызывайте `validateAndRefreshToken()` перед каждым запросом.
243
330
 
244
331
  ---
245
332
 
246
333
  ## Методы API: Уведомления и поиск
247
334
 
248
- ### getNotifications(limit, cursor, type?)
335
+ ### getNotifications(limit, offset, type?)
249
336
 
250
- Список уведомлений с фильтрацией по типу (`reply`, `like`, `wall_post`, `follow`, `comment`).
337
+ Список уведомлений. GET `/api/notifications/?offset=0&limit=20` `{ notifications: [], hasMore }`.
338
+
339
+ - **Параметры**: `limit` (по умолчанию 20), `offset` (смещение для пагинации), `type` (фильтр на клиенте).
251
340
 
252
341
  ### Прочие методы уведомлений
253
342
 
254
- - `getNotificationsByType(type, limit, cursor)` — получение уведомлений конкретного типа.
255
- - `markNotificationAsRead(notificationId)` — пометка прочитанным. Возвращает `{ success: true }`.
256
- - `markAllNotificationsAsRead()` — пометка всех уведомлений (экспериментально).
257
- - `getNotificationCount()` — счетчик непрочитанных сообщений. Возвращает `number`.
343
+ - `getNotificationsByType(type, limit, offset)` — уведомления конкретного типа. Возвращает `{ notifications: [], hasMore }`.
344
+ - `markNotificationAsRead(notificationId)` — пометка одного прочитанным. ⚠️ Эндпоинт POST `/api/notifications/{id}/read` **не подтверждён**.
345
+ - `markNotificationsAsReadBatch(ids)` — пометка нескольких. POST `/api/notifications/read-batch` → `{ success: true, count }`.
346
+ - `markAllNotificationsAsRead()` — пометка всех. POST `/api/notifications/read-all` `{ success: true }`.
347
+ - `getNotificationCount()` — счетчик непрочитанных. ⚠️ Эндпоинт GET `/api/notifications/count` **не подтверждён**. Альтернатива: `hasUnread` можно вычислить по `getNotifications()` (поле `read` у каждого).
258
348
 
259
349
  ### Поиск и рекомендации
260
350
 
261
- - `search(query, userLimit?, hashtagLimit?)` — универсальный поиск пользователей и хэштегов. Возвращает `{ users: [], hashtags: [] }`.
351
+ - `search(query, userLimit?, hashtagLimit?)` — универсальный поиск. ⚠️ Эндпоинт GET `/api/search/?q=&userLimit=&hashtagLimit=` **не подтверждён**. Возвращает `{ users: [], hashtags: [] }`.
262
352
  - `searchUsers(query, limit?)` — поиск только пользователей.
263
353
  - `searchHashtags(query, limit?)` — поиск только хэштегов.
264
354
  - `getTopClans()` — рейтинг кланов по количеству участников. **Возвращает массив** `Array<{ avatar, memberCount }>` или **`null`** при ошибке (не объект с полем `clans`).
@@ -269,7 +359,9 @@ const post = await client.createPost('Текст поста', 'image.jpg');
269
359
  ### Файлы и репорты
270
360
 
271
361
  - `uploadFile(filePath)` — загрузка файла через `/api/files/upload`. Возвращает `{ id, url, filename, mimeType, size }` или **`null`** при ошибке. Таймаут — `uploadTimeout` (по умолчанию 120 с). Используется автоматически при создании поста с изображением.
272
- - `report(targetType, targetId, reason?, description?)` — отправка репорта. `targetType`: `"post"`, `"comment"`, `"user"`. Возвращает `{ id, createdAt }`.
362
+ - `getFile(fileId)` — информация о файле. GET `/api/files/{id}`.
363
+ - `deleteFile(fileId)` — удалить файл. DELETE `/api/files/{id}`.
364
+ - `report(targetType, targetId, reason?, description?)` — отправка репорта. `targetType`: `"post"`, `"comment"`, `"user"`. `reason`: `"spam"`, `"violence"`, `"hate"`, `"adult"`, `"fraud"`, `"other"`. Возвращает `{ id, createdAt }`. При повторном репорте того же контента API возвращает 400: «Вы уже отправляли жалобу на этот контент».
273
365
  - `reportPost(postId, reason?, description?)` — репорт поста.
274
366
  - `reportComment(commentId, reason?, description?)` — репорт комментария.
275
367
  - `reportUser(userId, reason?, description?)` — репорт пользователя.
@@ -303,7 +395,7 @@ const post = await client.createPost('Текст поста', 'image.jpg');
303
395
  ### Уведомления
304
396
 
305
397
  - `hasUnreadNotifications()` — проверка наличия непрочитанных уведомлений. Возвращает `boolean`.
306
- - `getUnreadNotifications(limit, cursor)` — только непрочитанные уведомления. Возвращает `{ notifications: [], pagination: {} }`.
398
+ - `getUnreadNotifications(limit, offset)` — только непрочитанные. Возвращает `{ notifications: [], hasMore }`.
307
399
 
308
400
  ---
309
401
 
@@ -311,16 +403,28 @@ const post = await client.createPost('Текст поста', 'image.jpg');
311
403
 
312
404
  ### Пагинация
313
405
 
314
- Методы, возвращающие списки, используют курсорную пагинацию:
406
+ Разные методы используют разную пагинацию:
407
+
408
+ | Метод | Тип | Параметр | Пример ответа |
409
+ |-------|-----|----------|---------------|
410
+ | `getPosts`, `getComments`, `getPostsByHashtag`, `getLikedPosts` | cursor | `nextCursor` | `{ limit, nextCursor, hasMore }` |
411
+ | `getNotifications`, `getUnreadNotifications` | offset | `offset` | `{ notifications, hasMore }` |
412
+ | `getFollowers`, `getFollowing` | page | `page` | `{ page, limit, total, hasMore }` |
315
413
 
316
414
  ```javascript
415
+ // Посты — cursor
317
416
  const result = await client.getPosts('username', 20, 'new');
318
- // result = { posts: [...], pagination: { limit: 20, nextCursor: "...", hasMore: true } }
319
-
320
- // Следующая страница
321
417
  if (result.pagination.hasMore) {
322
418
  const nextPage = await client.getPosts('username', 20, 'new', result.pagination.nextCursor);
323
419
  }
420
+
421
+ // Уведомления — offset
422
+ const notif = await client.getNotifications(20, 0);
423
+ const next = await client.getNotifications(20, 20);
424
+
425
+ // Подписчики — page
426
+ const fol = await client.getFollowers('username', 1, 30);
427
+ const nextPage = await client.getFollowers('username', 2, 30);
324
428
  ```
325
429
 
326
430
  ### Структура поста
@@ -367,7 +471,7 @@ if (result.pagination.hasMore) {
367
471
 
368
472
  ---
369
473
 
370
- **Последнее обновление документации**: 2026-01-28.
474
+ **Последнее обновление документации**: 2026-01-31.
371
475
 
372
476
  ## Загрузка изображений
373
477
 
@@ -220,11 +220,8 @@ async function quickStart() {
220
220
  // ============================================
221
221
  console.log('🔔 Шаг 10: Получаю уведомления...\n');
222
222
 
223
- // Получаем список уведомлений
224
- // Параметры:
225
- // - limit: количество уведомлений (по умолчанию 20)
226
- // - cursor: курсор для пагинации (опционально)
227
- const notificationsResult = await client.getNotifications(5);
223
+ // Получаем список уведомлений (limit, offset)
224
+ const notificationsResult = await client.getNotifications(5, 0);
228
225
 
229
226
  if (notificationsResult && notificationsResult.notifications.length > 0) {
230
227
  console.log(`✅ Найдено уведомлений: ${notificationsResult.notifications.length}\n`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "itd-sdk-js",
3
- "version": "1.0.9",
3
+ "version": "1.1.0",
4
4
  "description": "Unofficial SDK for итд.com - Node.js library for working with API. Automatic token refresh, session management, and convenient methods for posts, comments, users, and notifications.",
5
5
  "main": "src/client.js",
6
6
  "type": "module",
package/src/auth.js CHANGED
@@ -119,16 +119,53 @@ export class AuthManager {
119
119
  }
120
120
 
121
121
  /**
122
- * Выход из аккаунта
123
- *
122
+ * Смена пароля. POST /api/v1/auth/change-password
123
+ * Требует cookies (refresh_token).
124
+ *
125
+ * @param {string} oldPassword - Текущий пароль
126
+ * @param {string} newPassword - Новый пароль
127
+ * @returns {Promise<Object|null>} Ответ API или null при ошибке
128
+ */
129
+ async changePassword(oldPassword, newPassword) {
130
+ if (!await this.client.auth.checkAuth()) {
131
+ console.error('Ошибка: необходим accessToken');
132
+ return null;
133
+ }
134
+ if (!this.hasRefreshToken()) {
135
+ console.error('Ошибка: необходим refresh_token в cookies');
136
+ return null;
137
+ }
138
+ try {
139
+ const url = `${this.client.baseUrl}/api/v1/auth/change-password`;
140
+ const response = await this.axios.post(url, {
141
+ oldPassword,
142
+ newPassword,
143
+ });
144
+ if (response.status === 200) {
145
+ return response.data;
146
+ }
147
+ return null;
148
+ } catch (error) {
149
+ console.error('Ошибка смены пароля:', error.message);
150
+ if (error.response) {
151
+ console.error('Response:', error.response.status, error.response.data);
152
+ }
153
+ return null;
154
+ }
155
+ }
156
+
157
+ /**
158
+ * Выход из аккаунта.
159
+ * POST /api/v1/auth/logout → 204
160
+ *
124
161
  * @returns {Promise<boolean>} True если успешно
125
162
  */
126
163
  async logout() {
127
164
  try {
128
- const logoutUrl = `${this.client.baseUrl}/api/v1/auth/sign-out`;
165
+ const logoutUrl = `${this.client.baseUrl}/api/v1/auth/logout`;
129
166
  const response = await this.axios.post(logoutUrl);
130
-
131
- if (response.status === 200) {
167
+
168
+ if (response.status === 200 || response.status === 204) {
132
169
  this.client.setAccessToken(null);
133
170
  try {
134
171
  this.client.cookieJar.removeAllCookiesSync();