meta-sovereign 0.49.14 → 0.49.16
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/js/src/server/background-jobs.js +3 -1
- package/js/src/server/backup-job.js +1 -0
- package/js/src/server/index.js +2 -2
- package/js/src/server/routes-telegram-channel-manage.js +79 -0
- package/js/src/server/routes-telegram-contact-extras.js +102 -0
- package/js/src/server/routes-telegram-emoji-groups.js +20 -0
- package/js/src/server/routes-telegram-security-extras.js +64 -0
- package/js/src/server/routes-telegram-storage.js +73 -0
- package/js/src/server/routes-telegram-translate-chat.js +31 -0
- package/js/src/server/routes-telegram-yextras.js +17 -0
- package/js/src/server/routes-telegram.js +6 -0
- package/js/src/sources/secret-chat-crypto.js +275 -0
- package/js/src/sources/secret-chat-session.js +178 -0
- package/js/src/sources/secret-chat-tl.js +418 -0
- package/js/src/sources/telegram-actions.js +25 -3
- package/js/src/sources/telegram-channel-manage.js +263 -0
- package/js/src/sources/telegram-chat-info.js +19 -0
- package/js/src/sources/telegram-chat-removal.js +21 -2
- package/js/src/sources/telegram-contact-extras.js +290 -0
- package/js/src/sources/telegram-emoji-groups.js +95 -0
- package/js/src/sources/telegram-format.js +39 -4
- package/js/src/sources/telegram-notify-extras.js +144 -0
- package/js/src/sources/telegram-security-extras.js +208 -0
- package/js/src/sources/telegram-security.js +5 -0
- package/js/src/sources/telegram-stickers.js +6 -1
- package/js/src/sources/telegram-storage.js +380 -0
- package/js/src/sources/telegram-translate-chat.js +57 -0
- package/js/src/sources/telegram-translate.js +5 -5
- package/js/src/sources/telegram-write-outcome.js +40 -0
- package/js/src/storage/backup.js +17 -3
- package/js/src/web/app.css +220 -1
- package/js/src/web/app.js +5 -0
- package/js/src/web/auto-download.js +37 -0
- package/js/src/web/chat-actions.js +50 -28
- package/js/src/web/chat-channel-limit.js +142 -0
- package/js/src/web/chat-contact-extras.js +396 -0
- package/js/src/web/chat-contact-share.js +109 -0
- package/js/src/web/chat-contacts-synced.js +64 -0
- package/js/src/web/chat-contacts-window.js +24 -1
- package/js/src/web/chat-drafts-clear.js +52 -24
- package/js/src/web/chat-edit.js +3 -0
- package/js/src/web/chat-emoji-custom.js +338 -0
- package/js/src/web/chat-emoji-status.js +21 -9
- package/js/src/web/chat-emoji-tools.js +17 -1
- package/js/src/web/chat-emoji.js +214 -72
- package/js/src/web/chat-failure.js +2 -0
- package/js/src/web/chat-group-stickers.js +3 -10
- package/js/src/web/chat-invite.js +12 -1
- package/js/src/web/chat-manage.js +303 -0
- package/js/src/web/chat-message.js +19 -8
- package/js/src/web/chat-paid-send.js +14 -8
- package/js/src/web/chat-privacy.js +19 -0
- package/js/src/web/chat-profile-extras.js +4 -4
- package/js/src/web/chat-public-link.js +314 -0
- package/js/src/web/chat-replies-block.js +91 -0
- package/js/src/web/chat-security-extras.js +303 -0
- package/js/src/web/chat-security-forgot.js +240 -0
- package/js/src/web/chat-security.js +9 -0
- package/js/src/web/chat-selection.js +28 -8
- package/js/src/web/chat-sign-in-code.js +62 -0
- package/js/src/web/chat-similar.js +14 -1
- package/js/src/web/chat-translate-bar.js +293 -0
- package/js/src/web/chat-translate.js +93 -27
- package/js/src/web/chat-translation-switch.js +20 -22
- package/js/src/web/chat-view.js +6 -0
- package/js/src/web/contact-links.js +171 -0
- package/js/src/web/dom-telegram-calls.js +53 -0
- package/js/src/web/dom.js +3 -1
- package/js/src/web/locales/en-chat-account.js +225 -0
- package/js/src/web/locales/hi-chat-account.js +222 -0
- package/js/src/web/locales/ru-chat-account.js +222 -0
- package/js/src/web/locales/zh-chat-account.js +206 -0
- package/js/src/web/message-text.js +5 -2
- package/js/src/web/passkey-codec.js +100 -0
- package/js/src/web/person-panel.js +3 -0
- package/js/src/web/settings-confirm.js +62 -0
- package/js/src/web/settings-fields.js +47 -0
- package/js/src/web/settings-media.js +21 -1
- package/js/src/web/settings-notify-extras.js +160 -0
- package/js/src/web/settings-notify.js +16 -4
- package/js/src/web/settings-storage.js +235 -0
- package/js/src/web/settings-view.js +5 -1
- package/js/src/web/sign-in-code-guard.js +91 -0
- package/js/src/web/translate-detect.js +108 -0
- package/js/src/web/translate-store.js +140 -0
- package/js/src/web/tutorial-clear.js +50 -4
- package/js/src/web/use-redraw.js +14 -0
- package/package.json +14 -2
|
@@ -78,14 +78,16 @@ export const backgroundJobs = ({ ctx, store, log, later, backups }) => {
|
|
|
78
78
|
});
|
|
79
79
|
const purge = cachePurgeFor({ store, log, later });
|
|
80
80
|
return {
|
|
81
|
+
// Returns a promise settled once a backup in flight has finished.
|
|
81
82
|
stopJobs: () => {
|
|
82
|
-
backup.stopBackups();
|
|
83
|
+
const backupDone = backup.stopBackups();
|
|
83
84
|
audience.stopAudienceSync();
|
|
84
85
|
purge.stopCachePurge();
|
|
85
86
|
// The other timers and pollers the server started with the port.
|
|
86
87
|
ctx.autoImport?.close();
|
|
87
88
|
ctx.whatsappSignIn?.stop().catch(() => {});
|
|
88
89
|
ctx.stopPulls?.();
|
|
90
|
+
return backupDone;
|
|
89
91
|
},
|
|
90
92
|
};
|
|
91
93
|
};
|
package/js/src/server/index.js
CHANGED
|
@@ -916,13 +916,13 @@ export const startServer = async ({
|
|
|
916
916
|
bus?.close();
|
|
917
917
|
ctx.replies.close().catch(() => {});
|
|
918
918
|
ctx.closeAutomations().catch(() => {});
|
|
919
|
-
ctx.stopJobs();
|
|
919
|
+
const jobsDone = ctx.stopJobs();
|
|
920
920
|
ctx.chatIndex.close();
|
|
921
921
|
stopAll(telegramAccount, ctx.telegramAccounts, ctx.telegramExtras);
|
|
922
922
|
wsHandle?.close();
|
|
923
923
|
signaling?.close();
|
|
924
924
|
closeFront();
|
|
925
|
-
server.close(() => resolve());
|
|
925
|
+
server.close(() => Promise.resolve(jobsDone).then(resolve, resolve));
|
|
926
926
|
for (const socket of sockets) {
|
|
927
927
|
socket.destroy();
|
|
928
928
|
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
// Managing a channel or group (R-Y216): the routes of the POSTS table in
|
|
2
|
+
// routes-telegram.js, each validated strictly before the account is asked.
|
|
3
|
+
// The source validates again; this keeps junk off the account. Deleting a
|
|
4
|
+
// chat for everyone is `remove-chat` with the action `destroy`.
|
|
5
|
+
//
|
|
6
|
+
// Its routes:
|
|
7
|
+
// POST /api/telegram/channel-username-check {chat, username} -> { ok,
|
|
8
|
+
// status } whether the public link is free, or a
|
|
9
|
+
// code: invalid, taken, too-many-public (R-Y216)
|
|
10
|
+
// POST /api/telegram/channel-username-save {chat, username} -> { ok } the
|
|
11
|
+
// public link set; '' makes the chat private
|
|
12
|
+
// POST /api/telegram/public-channels {} -> { ok, channels } the user's
|
|
13
|
+
// public channels, for "Revoke link"
|
|
14
|
+
// POST /api/telegram/public-link-revoke {chat} -> { ok } one of them
|
|
15
|
+
// made private
|
|
16
|
+
// POST /api/telegram/usernames-deactivate {chat} -> { ok } every
|
|
17
|
+
// collectible username of the chat deactivated
|
|
18
|
+
// POST /api/telegram/channel-color-save {chat, forProfile, color?, emoji?}
|
|
19
|
+
// -> { ok } the name or profile colour (boosts needed)
|
|
20
|
+
// POST /api/telegram/channel-emoji-status {chat, documentId, until?} ->
|
|
21
|
+
// { ok } the channel's emoji status (null removes it)
|
|
22
|
+
// POST /api/telegram/inactive-channels {} -> { ok, channels } channels the
|
|
23
|
+
// user could leave when there are too many
|
|
24
|
+
// POST /api/telegram/leave-channels {chats} -> { ok, left } the chosen
|
|
25
|
+
// inactive channels left
|
|
26
|
+
|
|
27
|
+
import { route } from './routes-telegram-admin-extras.js';
|
|
28
|
+
|
|
29
|
+
const CHANNEL = /^-100\d{1,20}$/;
|
|
30
|
+
const NAME = /^[A-Za-z][A-Za-z0-9_]{3,30}[A-Za-z0-9]$/;
|
|
31
|
+
const DIGITS = /^\d{1,20}$/;
|
|
32
|
+
const MAX_LEAVE = 100;
|
|
33
|
+
|
|
34
|
+
const channelOf = (b) => CHANNEL.test(String(b.chat ?? ''));
|
|
35
|
+
const nameOf = (b) => typeof b.username === 'string' && NAME.test(b.username);
|
|
36
|
+
const WHAT = 'chat required';
|
|
37
|
+
|
|
38
|
+
export const CHANNEL_MANAGE_POSTS = {
|
|
39
|
+
'channel-username-check': route(
|
|
40
|
+
'channelUsernameCheck',
|
|
41
|
+
'chat and username required',
|
|
42
|
+
(b) => channelOf(b) && nameOf(b)
|
|
43
|
+
),
|
|
44
|
+
'channel-username-save': route(
|
|
45
|
+
'channelUsernameSave',
|
|
46
|
+
'chat and username required',
|
|
47
|
+
(b) => channelOf(b) && (b.username === '' || nameOf(b))
|
|
48
|
+
),
|
|
49
|
+
'public-channels': route('publicChannels', WHAT, () => true),
|
|
50
|
+
'public-link-revoke': route('publicLinkRevoke', WHAT, channelOf),
|
|
51
|
+
'usernames-deactivate': route('usernamesDeactivate', WHAT, channelOf),
|
|
52
|
+
'channel-color-save': route(
|
|
53
|
+
'channelColorSave',
|
|
54
|
+
'chat and colour required',
|
|
55
|
+
(b) =>
|
|
56
|
+
channelOf(b) &&
|
|
57
|
+
typeof b.forProfile === 'boolean' &&
|
|
58
|
+
(b.color === undefined || Number.isInteger(b.color)) &&
|
|
59
|
+
(b.emoji === undefined || DIGITS.test(String(b.emoji)))
|
|
60
|
+
),
|
|
61
|
+
'channel-emoji-status': route(
|
|
62
|
+
'channelEmojiStatusSet',
|
|
63
|
+
'chat and status required',
|
|
64
|
+
(b) =>
|
|
65
|
+
channelOf(b) &&
|
|
66
|
+
(b.documentId === null || DIGITS.test(String(b.documentId))) &&
|
|
67
|
+
(b.until === undefined || Number.isInteger(b.until))
|
|
68
|
+
),
|
|
69
|
+
'inactive-channels': route('inactiveChannels', WHAT, () => true),
|
|
70
|
+
'leave-channels': route(
|
|
71
|
+
'leaveChannels',
|
|
72
|
+
'chats required',
|
|
73
|
+
(b) =>
|
|
74
|
+
Array.isArray(b.chats) &&
|
|
75
|
+
b.chats.length > 0 &&
|
|
76
|
+
b.chats.length <= MAX_LEAVE &&
|
|
77
|
+
b.chats.every((x) => CHANNEL.test(String(x)))
|
|
78
|
+
),
|
|
79
|
+
};
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
// Contact notes, share-my-contact links, phone links, photos for contacts,
|
|
2
|
+
// suggested birthdays, synced contacts and blocking from Replies (R-Y217):
|
|
3
|
+
// the routes of the POSTS table in routes-telegram.js, each validated
|
|
4
|
+
// strictly before the account is asked.
|
|
5
|
+
//
|
|
6
|
+
// Its routes:
|
|
7
|
+
// POST /api/telegram/contact-note {chat, note} -> { ok, note } the private
|
|
8
|
+
// note on a contact (at most 128 characters, "" clears)
|
|
9
|
+
// POST /api/telegram/contact-token {} -> { ok, url, expires } the link
|
|
10
|
+
// t.me/contact/<token> to share the user's contact
|
|
11
|
+
// POST /api/telegram/contact-token-open {token} -> { ok, chat, name } the
|
|
12
|
+
// person that link names
|
|
13
|
+
// POST /api/telegram/phone-resolve {phone} -> { ok, found, chat?, name? }
|
|
14
|
+
// the person with that number (t.me/+<digits>)
|
|
15
|
+
// POST /api/telegram/contact-photo {chat, mode, token?} -> { ok, mode }
|
|
16
|
+
// mode save (only the user sees it), suggest, or reset
|
|
17
|
+
// (the personal photo removed; no token)
|
|
18
|
+
// POST /api/telegram/birthday-suggest {chat, day, month, year?} -> { ok }
|
|
19
|
+
// POST /api/telegram/saved-contacts {} -> { ok, count } the imported
|
|
20
|
+
// contacts Telegram keeps
|
|
21
|
+
// POST /api/telegram/saved-contacts-reset {} -> { ok } those deleted
|
|
22
|
+
// POST /api/telegram/block-from-replies {msgId, deleteMessage?,
|
|
23
|
+
// deleteHistory?, reportSpam?} -> { ok } the sender
|
|
24
|
+
// of a message of the Replies chat blocked
|
|
25
|
+
|
|
26
|
+
import { route } from './routes-telegram-admin-extras.js';
|
|
27
|
+
import {
|
|
28
|
+
MODES,
|
|
29
|
+
NOTE_MAX,
|
|
30
|
+
PHONE_DIGITS,
|
|
31
|
+
TOKEN,
|
|
32
|
+
USER,
|
|
33
|
+
validMsgId,
|
|
34
|
+
} from '../sources/telegram-contact-extras.js';
|
|
35
|
+
|
|
36
|
+
const UPLOAD = /^[a-f0-9]{32}$/;
|
|
37
|
+
const user = (b) => USER.test(String(b.chat ?? ''));
|
|
38
|
+
const flag = (v) => v === undefined || typeof v === 'boolean';
|
|
39
|
+
const always = () => true;
|
|
40
|
+
|
|
41
|
+
export const CONTACT_EXTRAS_POSTS = {
|
|
42
|
+
'contact-note': route(
|
|
43
|
+
'contactNote',
|
|
44
|
+
'chat and note required',
|
|
45
|
+
(b) => user(b) && typeof b.note === 'string' && b.note.length <= NOTE_MAX,
|
|
46
|
+
(b) => ({ chat: String(b.chat), note: b.note })
|
|
47
|
+
),
|
|
48
|
+
'contact-token': route('contactToken', 'unsupported', always, () => ({})),
|
|
49
|
+
'contact-token-open': route(
|
|
50
|
+
'contactTokenOpen',
|
|
51
|
+
'token required',
|
|
52
|
+
(b) => typeof b.token === 'string' && TOKEN.test(b.token),
|
|
53
|
+
(b) => ({ token: b.token })
|
|
54
|
+
),
|
|
55
|
+
'phone-resolve': route(
|
|
56
|
+
'phoneResolve',
|
|
57
|
+
'phone required',
|
|
58
|
+
(b) =>
|
|
59
|
+
typeof b.phone === 'string' &&
|
|
60
|
+
PHONE_DIGITS.test(b.phone.replace(/^\+/, '')),
|
|
61
|
+
(b) => ({ phone: b.phone })
|
|
62
|
+
),
|
|
63
|
+
'contact-photo': route(
|
|
64
|
+
'contactPhoto',
|
|
65
|
+
'chat, mode and token required',
|
|
66
|
+
(b) =>
|
|
67
|
+
user(b) &&
|
|
68
|
+
MODES.includes(b.mode) &&
|
|
69
|
+
(b.mode === 'reset'
|
|
70
|
+
? b.token === undefined
|
|
71
|
+
: typeof b.token === 'string' && UPLOAD.test(b.token)),
|
|
72
|
+
(b) => ({ chat: String(b.chat), mode: b.mode, token: b.token })
|
|
73
|
+
),
|
|
74
|
+
'birthday-suggest': route(
|
|
75
|
+
'birthdaySuggest',
|
|
76
|
+
'chat, day and month required',
|
|
77
|
+
(b) => user(b) && Number.isInteger(b.day) && Number.isInteger(b.month),
|
|
78
|
+
({ chat, day, month, year }) => ({ chat: String(chat), day, month, year })
|
|
79
|
+
),
|
|
80
|
+
'saved-contacts': route('savedContacts', 'unsupported', always, () => ({})),
|
|
81
|
+
'saved-contacts-reset': route(
|
|
82
|
+
'savedContactsReset',
|
|
83
|
+
'unsupported',
|
|
84
|
+
always,
|
|
85
|
+
() => ({})
|
|
86
|
+
),
|
|
87
|
+
'block-from-replies': route(
|
|
88
|
+
'blockFromReplies',
|
|
89
|
+
'msgId required',
|
|
90
|
+
(b) =>
|
|
91
|
+
validMsgId(b.msgId) &&
|
|
92
|
+
flag(b.deleteMessage) &&
|
|
93
|
+
flag(b.deleteHistory) &&
|
|
94
|
+
flag(b.reportSpam),
|
|
95
|
+
({ msgId, deleteMessage, deleteHistory, reportSpam }) => ({
|
|
96
|
+
msgId,
|
|
97
|
+
deleteMessage,
|
|
98
|
+
deleteHistory,
|
|
99
|
+
reportSpam,
|
|
100
|
+
})
|
|
101
|
+
),
|
|
102
|
+
};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
// The emoji panel's Premium flag and category groups (R-Y214): the route
|
|
2
|
+
// of the POSTS table in routes-telegram.js, validated before the account
|
|
3
|
+
// is asked.
|
|
4
|
+
//
|
|
5
|
+
// Its routes:
|
|
6
|
+
// POST /api/telegram/emoji-panel-info {status?} -> { ok, premium, groups:
|
|
7
|
+
// [{ title, iconEmojiId, emoticons }] } whether the
|
|
8
|
+
// account has Premium and Telegram's emoji groups
|
|
9
|
+
// (status: true, the emoji status picker's)
|
|
10
|
+
|
|
11
|
+
import { route } from './routes-telegram-admin-extras.js';
|
|
12
|
+
|
|
13
|
+
export const EMOJI_GROUPS_POSTS = {
|
|
14
|
+
'emoji-panel-info': route(
|
|
15
|
+
'emojiPanelInfo',
|
|
16
|
+
'status must be true or false',
|
|
17
|
+
(b) => b.status === undefined || typeof b.status === 'boolean',
|
|
18
|
+
(b) => ({ status: b.status === true })
|
|
19
|
+
),
|
|
20
|
+
};
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
// More of Privacy and Security (R-Y218): the routes of the POSTS table in
|
|
2
|
+
// routes-telegram.js, each validated strictly before the account is asked.
|
|
3
|
+
// A code in a body is passed on and never kept.
|
|
4
|
+
//
|
|
5
|
+
// Its routes:
|
|
6
|
+
// POST /api/telegram/login-email-send {email} -> { ok, pattern, length }
|
|
7
|
+
// POST /api/telegram/login-email-verify {code} -> { ok, email }
|
|
8
|
+
// POST /api/telegram/recovery-request -> { ok, pattern } a code mailed to
|
|
9
|
+
// the recovery email
|
|
10
|
+
// POST /api/telegram/recovery-confirm {code} -> { ok } the password gone
|
|
11
|
+
// POST /api/telegram/password-reset -> { ok, result: 'ok' | 'wait' |
|
|
12
|
+
// 'failed-wait', until }
|
|
13
|
+
// POST /api/telegram/password-reset-cancel -> { ok }
|
|
14
|
+
// POST /api/telegram/passkeys -> { ok, passkeys: [{ id, name, created,
|
|
15
|
+
// lastUsed }] }
|
|
16
|
+
// POST /api/telegram/passkey-options -> { ok, options } WebAuthn JSON
|
|
17
|
+
// POST /api/telegram/passkey-register {id, rawId, clientData,
|
|
18
|
+
// attestation} -> { ok, passkey } (base64url strings)
|
|
19
|
+
// POST /api/telegram/passkey-delete {id} -> { ok }
|
|
20
|
+
// POST /api/telegram/sign-in-codes -> { ok, codes } fresh codes from 777000
|
|
21
|
+
// POST /api/telegram/invalidate-codes {codes: ['12345']} -> { ok }
|
|
22
|
+
|
|
23
|
+
import { route } from './routes-telegram-admin-extras.js';
|
|
24
|
+
|
|
25
|
+
const EMAIL = /^[^\s@]{1,64}@[^\s@]{1,255}$/;
|
|
26
|
+
const CODE = /^[0-9A-Za-z]{1,16}$/;
|
|
27
|
+
const str = (v, max) =>
|
|
28
|
+
typeof v === 'string' && v.length > 0 && v.length <= max;
|
|
29
|
+
const nothing = () => true;
|
|
30
|
+
const code = (b) => CODE.test(String(b.code ?? ''));
|
|
31
|
+
|
|
32
|
+
export const SECURITY_EXTRAS_POSTS = {
|
|
33
|
+
'login-email-send': route('loginEmailSend', 'a valid email required', (b) =>
|
|
34
|
+
EMAIL.test(String(b.email ?? ''))
|
|
35
|
+
),
|
|
36
|
+
'login-email-verify': route('loginEmailVerify', 'the code required', code),
|
|
37
|
+
'recovery-request': route('recoveryRequest', 'no body', nothing),
|
|
38
|
+
'recovery-confirm': route('recoveryConfirm', 'the code required', code),
|
|
39
|
+
'password-reset': route('passwordReset', 'no body', nothing),
|
|
40
|
+
'password-reset-cancel': route('passwordResetCancel', 'no body', nothing),
|
|
41
|
+
passkeys: route('passkeys', 'no body', nothing),
|
|
42
|
+
'passkey-options': route('passkeyOptions', 'no body', nothing),
|
|
43
|
+
'passkey-register': route(
|
|
44
|
+
'passkeyRegister',
|
|
45
|
+
'id, rawId, clientData and attestation required',
|
|
46
|
+
(b) =>
|
|
47
|
+
['id', 'rawId', 'clientData', 'attestation'].every((k) =>
|
|
48
|
+
str(b[k], 100_000)
|
|
49
|
+
)
|
|
50
|
+
),
|
|
51
|
+
'passkey-delete': route('passkeyDelete', 'the passkey id required', (b) =>
|
|
52
|
+
str(b.id, 1024)
|
|
53
|
+
),
|
|
54
|
+
'sign-in-codes': route('signInCodes', 'no body', nothing),
|
|
55
|
+
'invalidate-codes': route(
|
|
56
|
+
'invalidateCodes',
|
|
57
|
+
'one to ten codes required',
|
|
58
|
+
(b) =>
|
|
59
|
+
Array.isArray(b.codes) &&
|
|
60
|
+
b.codes.length > 0 &&
|
|
61
|
+
b.codes.length <= 10 &&
|
|
62
|
+
b.codes.every((v) => /^\d{5,6}$/.test(String(v)))
|
|
63
|
+
),
|
|
64
|
+
};
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
// Local storage management, reaction notifications, resetting the
|
|
2
|
+
// notification settings and Telegram's automatic-download preset (R-Y215):
|
|
3
|
+
// the routes of the POSTS table in routes-telegram.js, each validated
|
|
4
|
+
// strictly before the account is asked.
|
|
5
|
+
//
|
|
6
|
+
// Its routes:
|
|
7
|
+
// POST /api/telegram/storage-usage {} -> { ok, total, kinds, chats,
|
|
8
|
+
// limits } the media cache by kind (photos, videos,
|
|
9
|
+
// voice, files, stickers, other) and by chat
|
|
10
|
+
// POST /api/telegram/storage-clear {kind} | {all: true} -> { ok,
|
|
11
|
+
// removed: { bytes, files } } only files inside the
|
|
12
|
+
// media cache are removed
|
|
13
|
+
// POST /api/telegram/storage-limits {} -> { ok, maxGb, olderDays }
|
|
14
|
+
// POST /api/telegram/storage-limits-set {maxGb, olderDays} -> { ok, ...,
|
|
15
|
+
// removed } maxGb 0, 1, 5 or 20; olderDays 0, 7, 30
|
|
16
|
+
// or 365 (0 is none); applied at once
|
|
17
|
+
// POST /api/telegram/reaction-notify {} -> { ok, messages, stories,
|
|
18
|
+
// previews, sound } who is told of reactions
|
|
19
|
+
// ('nobody', 'contacts', 'all')
|
|
20
|
+
// POST /api/telegram/reaction-notify-set {messages?, stories?, previews?,
|
|
21
|
+
// sound?} -> the same row
|
|
22
|
+
// POST /api/telegram/notify-reset {} -> { ok } every notification
|
|
23
|
+
// setting back to Telegram's default
|
|
24
|
+
// POST /api/telegram/auto-download-preset {} -> { ok, medium: {
|
|
25
|
+
// disabled, photoMax, videoMax, fileMax } } bytes
|
|
26
|
+
|
|
27
|
+
import { validClear, validLimits } from '../sources/telegram-storage.js';
|
|
28
|
+
import { validReactionChange } from '../sources/telegram-notify-extras.js';
|
|
29
|
+
import { route } from './routes-telegram-admin-extras.js';
|
|
30
|
+
|
|
31
|
+
const anyone = () => true;
|
|
32
|
+
const nothing = () => ({});
|
|
33
|
+
|
|
34
|
+
export const STORAGE_POSTS = {
|
|
35
|
+
'storage-usage': route('storageUsage', 'not supported', anyone, nothing),
|
|
36
|
+
'storage-clear': route(
|
|
37
|
+
'storageClear',
|
|
38
|
+
'a kind or all required',
|
|
39
|
+
validClear,
|
|
40
|
+
(b) => (b.all === true ? { all: true } : { kind: b.kind })
|
|
41
|
+
),
|
|
42
|
+
'storage-limits': route('storageLimits', 'not supported', anyone, nothing),
|
|
43
|
+
'storage-limits-set': route(
|
|
44
|
+
'storageLimitsSet',
|
|
45
|
+
'maxGb and olderDays required',
|
|
46
|
+
validLimits,
|
|
47
|
+
(b) => ({ maxGb: b.maxGb, olderDays: b.olderDays })
|
|
48
|
+
),
|
|
49
|
+
'reaction-notify': route(
|
|
50
|
+
'reactionNotifyGet',
|
|
51
|
+
'not supported',
|
|
52
|
+
anyone,
|
|
53
|
+
nothing
|
|
54
|
+
),
|
|
55
|
+
'reaction-notify-set': route(
|
|
56
|
+
'reactionNotifySet',
|
|
57
|
+
'a change required',
|
|
58
|
+
validReactionChange,
|
|
59
|
+
(b) => ({
|
|
60
|
+
messages: b.messages,
|
|
61
|
+
stories: b.stories,
|
|
62
|
+
previews: b.previews,
|
|
63
|
+
sound: b.sound,
|
|
64
|
+
})
|
|
65
|
+
),
|
|
66
|
+
'notify-reset': route('notifyResetAll', 'not supported', anyone, nothing),
|
|
67
|
+
'auto-download-preset': route(
|
|
68
|
+
'autoDownloadPreset',
|
|
69
|
+
'not supported',
|
|
70
|
+
anyone,
|
|
71
|
+
nothing
|
|
72
|
+
),
|
|
73
|
+
};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
// The translate bar and the summary (R-Y213): routes of the POSTS table in
|
|
2
|
+
// routes-telegram.js, validated strictly before the account is asked.
|
|
3
|
+
//
|
|
4
|
+
// Its routes:
|
|
5
|
+
// POST /api/telegram/translate-account {} -> { ok, premium } whether the
|
|
6
|
+
// account has Premium (the bar is offered only then)
|
|
7
|
+
// POST /api/telegram/summarize {chat, id, to?} -> { ok, text, entities }
|
|
8
|
+
// a long message summarized (messages.summarizeText);
|
|
9
|
+
// refusals come as { ok: false, code }
|
|
10
|
+
|
|
11
|
+
import { route } from './routes-telegram-admin-extras.js';
|
|
12
|
+
|
|
13
|
+
const LANG = /^[a-z]{2,3}(-[A-Za-z]{2,4})?$/;
|
|
14
|
+
|
|
15
|
+
export const TRANSLATE_CHAT_POSTS = {
|
|
16
|
+
'translate-account': route(
|
|
17
|
+
'translateAccount',
|
|
18
|
+
'nothing required',
|
|
19
|
+
() => true,
|
|
20
|
+
() => ({})
|
|
21
|
+
),
|
|
22
|
+
summarize: route(
|
|
23
|
+
'summarizeMessage',
|
|
24
|
+
'chat and id required',
|
|
25
|
+
(b) =>
|
|
26
|
+
/^-?\d{1,20}$/.test(String(b.chat ?? '')) &&
|
|
27
|
+
Number.isInteger(b.id) &&
|
|
28
|
+
b.id > 0 &&
|
|
29
|
+
(b.to === undefined || (typeof b.to === 'string' && LANG.test(b.to)))
|
|
30
|
+
),
|
|
31
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// The route tables of the R-Y213..R-Y216 features in one spread, so that
|
|
2
|
+
// routes-telegram.js stays under its line limit. Each table documents its
|
|
3
|
+
// own routes in its file's header:
|
|
4
|
+
// routes-telegram-translate-chat.js (R-Y213), -emoji-groups.js (R-Y214),
|
|
5
|
+
// -storage.js (R-Y215), -channel-manage.js (R-Y216).
|
|
6
|
+
|
|
7
|
+
import { TRANSLATE_CHAT_POSTS } from './routes-telegram-translate-chat.js';
|
|
8
|
+
import { EMOJI_GROUPS_POSTS } from './routes-telegram-emoji-groups.js';
|
|
9
|
+
import { STORAGE_POSTS } from './routes-telegram-storage.js';
|
|
10
|
+
import { CHANNEL_MANAGE_POSTS } from './routes-telegram-channel-manage.js';
|
|
11
|
+
|
|
12
|
+
export const YEXTRAS_POSTS = {
|
|
13
|
+
...TRANSLATE_CHAT_POSTS,
|
|
14
|
+
...EMOJI_GROUPS_POSTS,
|
|
15
|
+
...STORAGE_POSTS,
|
|
16
|
+
...CHANNEL_MANAGE_POSTS,
|
|
17
|
+
};
|
|
@@ -206,6 +206,7 @@ import { WEB_APPS_POSTS } from './routes-telegram-web-apps.js';
|
|
|
206
206
|
import { BOT_LOGIN_POSTS } from './routes-telegram-bot-login.js';
|
|
207
207
|
import { ADMIN_POSTS } from './routes-telegram-admin.js';
|
|
208
208
|
import { GROUP_EXTRAS_POSTS } from './routes-telegram-group-extras.js';
|
|
209
|
+
import { YEXTRAS_POSTS } from './routes-telegram-yextras.js';
|
|
209
210
|
import {
|
|
210
211
|
INSTANT_VIEW_GETS,
|
|
211
212
|
INSTANT_VIEW_POSTS,
|
|
@@ -242,6 +243,7 @@ import { FOLDER_EDIT_POSTS } from './routes-telegram-folder-edit.js';
|
|
|
242
243
|
import { CHATLIST_POSTS } from './routes-telegram-chatlists.js';
|
|
243
244
|
import { STICKER_SETTINGS_POSTS } from './routes-telegram-sticker-settings.js';
|
|
244
245
|
import { CHAT_THEME_POSTS } from './routes-telegram-chat-themes.js';
|
|
246
|
+
import { CONTACT_EXTRAS_POSTS } from './routes-telegram-contact-extras.js';
|
|
245
247
|
import { CLOUD_THEME_POSTS } from './routes-telegram-cloud-themes.js';
|
|
246
248
|
import { COMMON_CHATS_POSTS } from './routes-telegram-common-chats.js';
|
|
247
249
|
import { STATS_POSTS } from './routes-telegram-stats.js';
|
|
@@ -266,6 +268,7 @@ import { EMOJI_STATUS_POSTS } from './routes-telegram-emoji-status.js';
|
|
|
266
268
|
import { ROUND_POSTS } from './routes-telegram-round.js';
|
|
267
269
|
import { PRIVACY_POSTS } from './routes-telegram-privacy.js';
|
|
268
270
|
import { SECURITY_POSTS } from './routes-telegram-security.js';
|
|
271
|
+
import { SECURITY_EXTRAS_POSTS } from './routes-telegram-security-extras.js';
|
|
269
272
|
import { SHARE_POSTS } from './routes-telegram-share.js';
|
|
270
273
|
import { INLINE_POSTS } from './routes-telegram-inline.js';
|
|
271
274
|
import { MESSAGE_LINK_POSTS } from './routes-telegram-message-links.js';
|
|
@@ -1020,6 +1023,8 @@ const POSTS = {
|
|
|
1020
1023
|
: [400, { error: 'chat and a change required', code: 'bad-request' }],
|
|
1021
1024
|
...ADMIN_POSTS,
|
|
1022
1025
|
...EPHEMERAL_POSTS,
|
|
1026
|
+
...YEXTRAS_POSTS,
|
|
1027
|
+
...CONTACT_EXTRAS_POSTS,
|
|
1023
1028
|
...GROUP_EXTRAS_POSTS,
|
|
1024
1029
|
...INSTANT_VIEW_POSTS,
|
|
1025
1030
|
...STICKER_EXTRAS_POSTS,
|
|
@@ -1069,6 +1074,7 @@ const POSTS = {
|
|
|
1069
1074
|
...ROUND_POSTS,
|
|
1070
1075
|
...PRIVACY_POSTS,
|
|
1071
1076
|
...SECURITY_POSTS,
|
|
1077
|
+
...SECURITY_EXTRAS_POSTS,
|
|
1072
1078
|
...SHARE_POSTS,
|
|
1073
1079
|
...INLINE_POSTS,
|
|
1074
1080
|
...TTL_POSTS,
|