Browse Source

remove some polyfills

master
Eduard Kuzmenko 3 years ago
parent
commit
0858131ede
  1. 3
      src/components/appSearchSuper..ts
  2. 3
      src/components/appSelectPeers.ts
  3. 5
      src/components/audio.ts
  4. 3
      src/components/call/description.ts
  5. 3
      src/components/chat/bubbleGroups.ts
  6. 3
      src/components/chat/bubbles.ts
  7. 3
      src/components/chat/input.ts
  8. 3
      src/components/lazyLoadQueue.ts
  9. 3
      src/components/peerProfileAvatars.ts
  10. 3
      src/components/poll.ts
  11. 3
      src/components/sidebarLeft/tabs/activeSessions.ts
  12. 9
      src/components/wrappers.ts
  13. 4
      src/helpers/array/findAndSplice.ts
  14. 9
      src/helpers/array/randomize.ts
  15. 3
      src/helpers/bytes/addPadding.ts
  16. 3
      src/helpers/eventListenerBase.ts
  17. 11
      src/helpers/string/toHHMMSS.ts
  18. 3
      src/lib/appManagers/appChatsManager.ts
  19. 2
      src/lib/appManagers/appMessagesManager.ts
  20. 5
      src/lib/appManagers/appReactionsManager.ts
  21. 3
      src/lib/appManagers/appStickersManager.ts
  22. 3
      src/lib/appManagers/appUsersManager.ts
  23. 3
      src/lib/crypto/generateDh.ts
  24. 3
      src/lib/crypto/srp.ts
  25. 9
      src/lib/mediaPlayer.ts
  26. 5
      src/lib/mtproto/apiFileManager.ts
  27. 11
      src/lib/mtproto/authorizer.ts
  28. 7
      src/lib/mtproto/networker.ts
  29. 3
      src/lib/mtproto/passwordManager.ts
  30. 2
      src/lib/mtproto/tl_utils.ts
  31. 5
      src/lib/mtproto/transports/obfuscation.ts
  32. 3
      src/lib/mtproto/transports/padded.ts
  33. 3
      src/lib/mtproto/transports/tcpObfuscated.ts
  34. 65
      src/lib/polyfill.ts

3
src/components/appSearchSuper..ts

@ -54,6 +54,7 @@ import getObjectKeysAndSort from "../helpers/object/getObjectKeysAndSort";
import safeAssign from "../helpers/object/safeAssign"; import safeAssign from "../helpers/object/safeAssign";
import escapeRegExp from "../helpers/string/escapeRegExp"; import escapeRegExp from "../helpers/string/escapeRegExp";
import limitSymbols from "../helpers/string/limitSymbols"; import limitSymbols from "../helpers/string/limitSymbols";
import findAndSplice from "../helpers/array/findAndSplice";
//const testScroll = false; //const testScroll = false;
@ -1476,7 +1477,7 @@ export default class AppSearchSuper {
}); });
if(peerId.isUser()) { if(peerId.isUser()) {
toLoad.findAndSplice(mediaTab => mediaTab.type === 'members'); findAndSplice(toLoad, mediaTab => mediaTab.type === 'members');
} }
if(!toLoad.length) { if(!toLoad.length) {

3
src/components/appSelectPeers.ts

@ -27,6 +27,7 @@ import { attachClickEvent } from "../helpers/dom/clickEvent";
import filterUnique from "../helpers/array/filterUnique"; import filterUnique from "../helpers/array/filterUnique";
import indexOfAndSplice from "../helpers/array/indexOfAndSplice"; import indexOfAndSplice from "../helpers/array/indexOfAndSplice";
import safeAssign from "../helpers/object/safeAssign"; import safeAssign from "../helpers/object/safeAssign";
import findAndSplice from "../helpers/array/findAndSplice";
type SelectSearchPeerType = 'contacts' | 'dialogs' | 'channelParticipants'; type SelectSearchPeerType = 'contacts' | 'dialogs' | 'channelParticipants';
@ -312,7 +313,7 @@ export default class AppSelectPeers {
const newOffsetIndex = dialogs[dialogs.length - 1].index || 0; const newOffsetIndex = dialogs[dialogs.length - 1].index || 0;
dialogs = dialogs.slice(); dialogs = dialogs.slice();
dialogs.findAndSplice(d => d.peerId === rootScope.myId); // no my account findAndSplice(dialogs, d => d.peerId === rootScope.myId); // no my account
if(this.chatRightsAction) { if(this.chatRightsAction) {
dialogs = dialogs.filter(d => this.filterByRights(d.peerId)); dialogs = dialogs.filter(d => this.filterByRights(d.peerId));

5
src/components/audio.ts

@ -31,6 +31,7 @@ import { NULL_PEER_ID } from "../lib/mtproto/mtproto_config";
import formatBytes from "../helpers/formatBytes"; import formatBytes from "../helpers/formatBytes";
import { animateSingle } from "../helpers/animation"; import { animateSingle } from "../helpers/animation";
import clamp from "../helpers/number/clamp"; import clamp from "../helpers/number/clamp";
import toHHMMSS from "../helpers/string/toHHMMSS";
rootScope.addEventListener('messages_media_read', ({mids, peerId}) => { rootScope.addEventListener('messages_media_read', ({mids, peerId}) => {
mids.forEach(mid => { mids.forEach(mid => {
@ -423,7 +424,7 @@ export default class AudioElement extends HTMLElement {
const isOutgoing = this.message.pFlags.is_outgoing; const isOutgoing = this.message.pFlags.is_outgoing;
const uploading = isOutgoing && this.preloader; const uploading = isOutgoing && this.preloader;
const durationStr = String(doc.duration | 0).toHHMMSS(); const durationStr = toHHMMSS(doc.duration | 0);
this.innerHTML = ` this.innerHTML = `
<div class="audio-toggle audio-ico"> <div class="audio-toggle audio-ico">
@ -466,7 +467,7 @@ export default class AudioElement extends HTMLElement {
this.onTypeDisconnect = onTypeLoad(); this.onTypeDisconnect = onTypeLoad();
const getTimeStr = () => String(audio.currentTime | 0).toHHMMSS() + (isVoice ? (' / ' + durationStr) : ''); const getTimeStr = () => toHHMMSS(audio.currentTime | 0) + (isVoice ? (' / ' + durationStr) : '');
const onPlay = () => { const onPlay = () => {
audioTimeDiv.innerText = getTimeStr(); audioTimeDiv.innerText = getTimeStr();

3
src/components/call/description.ts

@ -5,6 +5,7 @@
*/ */
import replaceContent from "../../helpers/dom/replaceContent"; import replaceContent from "../../helpers/dom/replaceContent";
import toHHMMSS from "../../helpers/string/toHHMMSS";
import CALL_STATE from "../../lib/calls/callState"; import CALL_STATE from "../../lib/calls/callState";
import { i18n, LangPackKey } from "../../lib/langPack"; import { i18n, LangPackKey } from "../../lib/langPack";
@ -43,7 +44,7 @@ export default class CallDescriptionElement {
element.classList.add('call-description-duration'); element.classList.add('call-description-duration');
const setTime = () => { const setTime = () => {
element.innerText = ('' + instance.duration).toHHMMSS(true); element.innerText = toHHMMSS(instance.duration, true);
}; };
this.interval = window.setInterval(setTime, 1000); this.interval = window.setInterval(setTime, 1000);

3
src/components/chat/bubbleGroups.ts

@ -9,6 +9,7 @@ import rootScope from "../../lib/rootScope";
import { MyMessage } from "../../lib/appManagers/appMessagesManager"; import { MyMessage } from "../../lib/appManagers/appMessagesManager";
import type Chat from "./chat"; import type Chat from "./chat";
import indexOfAndSplice from "../../helpers/array/indexOfAndSplice"; import indexOfAndSplice from "../../helpers/array/indexOfAndSplice";
import findAndSplice from "../../helpers/array/findAndSplice";
type Group = {bubble: HTMLElement, mid: number, timestamp: number}[]; type Group = {bubble: HTMLElement, mid: number, timestamp: number}[];
type BubbleGroup = {timestamp: number, fromId: PeerId, mid: number, group: Group}; type BubbleGroup = {timestamp: number, fromId: PeerId, mid: number, group: Group};
@ -27,7 +28,7 @@ export default class BubbleGroups {
const details = this.detailsMap.get(bubble); const details = this.detailsMap.get(bubble);
if(details) { if(details) {
if(details.group.length) { if(details.group.length) {
details.group.findAndSplice(d => d.bubble === bubble); findAndSplice(details.group, d => d.bubble === bubble);
if(!details.group.length) { if(!details.group.length) {
indexOfAndSplice(this.groups, details.group); indexOfAndSplice(this.groups, details.group);
} else { } else {

3
src/components/chat/bubbles.ts

@ -94,6 +94,7 @@ import ScrollSaver from "../../helpers/scrollSaver";
import getObjectKeysAndSort from "../../helpers/object/getObjectKeysAndSort"; import getObjectKeysAndSort from "../../helpers/object/getObjectKeysAndSort";
import forEachReverse from "../../helpers/array/forEachReverse"; import forEachReverse from "../../helpers/array/forEachReverse";
import formatNumber from "../../helpers/number/formatNumber"; import formatNumber from "../../helpers/number/formatNumber";
import findAndSplice from "../../helpers/array/findAndSplice";
const USE_MEDIA_TAILS = false; const USE_MEDIA_TAILS = false;
const IGNORE_ACTIONS: Set<Message.messageService['action']['_']> = new Set([ const IGNORE_ACTIONS: Set<Message.messageService['action']['_']> = new Set([
@ -4148,7 +4149,7 @@ export default class ChatBubbles {
const subtitle = i18n('NoMessagesGreetingsDescription'); const subtitle = i18n('NoMessagesGreetingsDescription');
subtitle.classList.add('center', BASE_CLASS + '-subtitle'); subtitle.classList.add('center', BASE_CLASS + '-subtitle');
this.messagesQueue.findAndSplice(q => q.bubble === bubble); findAndSplice(this.messagesQueue, q => q.bubble === bubble);
const stickerDiv = document.createElement('div'); const stickerDiv = document.createElement('div');
stickerDiv.classList.add(BASE_CLASS + '-sticker'); stickerDiv.classList.add(BASE_CLASS + '-sticker');

3
src/components/chat/input.ts

@ -92,6 +92,7 @@ import callbackify from '../../helpers/callbackify';
import ChatBotCommands from './botCommands'; import ChatBotCommands from './botCommands';
import copy from '../../helpers/object/copy'; import copy from '../../helpers/object/copy';
import indexOfAndSplice from '../../helpers/array/indexOfAndSplice'; import indexOfAndSplice from '../../helpers/array/indexOfAndSplice';
import toHHMMSS from '../../helpers/string/toHHMMSS';
const RECORD_MIN_TIME = 500; const RECORD_MIN_TIME = 500;
const POSTING_MEDIA_NOT_ALLOWED = 'Posting media content isn\'t allowed in this group.'; const POSTING_MEDIA_NOT_ALLOWED = 'Posting media content isn\'t allowed in this group.';
@ -2262,7 +2263,7 @@ export default class ChatInput {
let diff = Date.now() - this.recordStartTime; let diff = Date.now() - this.recordStartTime;
let ms = diff % 1000; let ms = diff % 1000;
let formatted = ('' + (diff / 1000)).toHHMMSS() + ',' + ('00' + Math.round(ms / 10)).slice(-2); let formatted = toHHMMSS(diff / 1000) + ',' + ('00' + Math.round(ms / 10)).slice(-2);
this.recordTimeEl.innerText = formatted; this.recordTimeEl.innerText = formatted;

3
src/components/lazyLoadQueue.ts

@ -9,6 +9,7 @@ import VisibilityIntersector, { OnVisibilityChange } from "./visibilityIntersect
import throttle from "../helpers/schedulers/throttle"; import throttle from "../helpers/schedulers/throttle";
import findAndSpliceAll from "../helpers/array/findAndSpliceAll"; import findAndSpliceAll from "../helpers/array/findAndSpliceAll";
import indexOfAndSplice from "../helpers/array/indexOfAndSplice"; import indexOfAndSplice from "../helpers/array/indexOfAndSplice";
import findAndSplice from "../helpers/array/findAndSplice";
type LazyLoadElementBase = { type LazyLoadElementBase = {
load: () => Promise<any> load: () => Promise<any>
@ -252,7 +253,7 @@ export default class LazyLoadQueue extends LazyLoadQueueIntersector {
}; };
protected getItem() { protected getItem() {
return this.queue.findAndSplice(item => item.wasSeen); return findAndSplice(this.queue, item => item.wasSeen);
} }
public async processItem(item: LazyLoadElement) { public async processItem(item: LazyLoadElement) {

3
src/components/peerProfileAvatars.ts

@ -6,6 +6,7 @@
import IS_PARALLAX_SUPPORTED from "../environment/parallaxSupport"; import IS_PARALLAX_SUPPORTED from "../environment/parallaxSupport";
import { IS_TOUCH_SUPPORTED } from "../environment/touchSupport"; import { IS_TOUCH_SUPPORTED } from "../environment/touchSupport";
import findAndSplice from "../helpers/array/findAndSplice";
import { cancelEvent } from "../helpers/dom/cancelEvent"; import { cancelEvent } from "../helpers/dom/cancelEvent";
import { attachClickEvent } from "../helpers/dom/clickEvent"; import { attachClickEvent } from "../helpers/dom/clickEvent";
import filterChatPhotosMessages from "../helpers/filterChatPhotosMessages"; import filterChatPhotosMessages from "../helpers/filterChatPhotosMessages";
@ -286,7 +287,7 @@ export default class PeerProfileAvatars {
if(!listLoader.current) { if(!listLoader.current) {
const chatFull = result[0]; const chatFull = result[0];
const message = value.history.findAndSplice(m => { const message = findAndSplice(value.history, m => {
return ((m as Message.messageService).action as MessageAction.messageActionChannelEditPhoto).photo.id === chatFull.chat_photo.id; return ((m as Message.messageService).action as MessageAction.messageActionChannelEditPhoto).photo.id === chatFull.chat_photo.id;
}) as Message.messageService; }) as Message.messageService;

3
src/components/poll.ts

@ -23,6 +23,7 @@ import { attachClickEvent, detachClickEvent } from "../helpers/dom/clickEvent";
import replaceContent from "../helpers/dom/replaceContent"; import replaceContent from "../helpers/dom/replaceContent";
import windowSize from "../helpers/windowSize"; import windowSize from "../helpers/windowSize";
import { Poll, PollResults } from "../layer"; import { Poll, PollResults } from "../layer";
import toHHMMSS from "../helpers/string/toHHMMSS";
let lineTotalLength = 0; let lineTotalLength = 0;
const tailLength = 9; const tailLength = 9;
@ -342,7 +343,7 @@ export default class PollElement extends HTMLElement {
const time = Date.now(); const time = Date.now();
const percents = (closeTime - time) / period; const percents = (closeTime - time) / period;
const timeLeft = (closeTime - time) / 1000 + 1 | 0; const timeLeft = (closeTime - time) / 1000 + 1 | 0;
timeLeftDiv.innerHTML = String(timeLeft).toHHMMSS(); timeLeftDiv.innerHTML = toHHMMSS(timeLeft);
if (timeLeft <= 5) { if (timeLeft <= 5) {
timeLeftDiv.style.color = '#ee545c'; timeLeftDiv.style.color = '#ee545c';

3
src/components/sidebarLeft/tabs/activeSessions.ts

@ -21,6 +21,7 @@ import findUpClassName from "../../../helpers/dom/findUpClassName";
import { attachClickEvent } from "../../../helpers/dom/clickEvent"; import { attachClickEvent } from "../../../helpers/dom/clickEvent";
import toggleDisability from "../../../helpers/dom/toggleDisability"; import toggleDisability from "../../../helpers/dom/toggleDisability";
import { SliderSuperTabEventable } from "../../sliderTab"; import { SliderSuperTabEventable } from "../../sliderTab";
import findAndSplice from "../../../helpers/array/findAndSplice";
export default class AppActiveSessionsTab extends SliderSuperTabEventable { export default class AppActiveSessionsTab extends SliderSuperTabEventable {
public authorizations: Authorization.authorization[]; public authorizations: Authorization.authorization[];
@ -58,7 +59,7 @@ export default class AppActiveSessionsTab extends SliderSuperTabEventable {
caption: 'ClearOtherSessionsHelp' caption: 'ClearOtherSessionsHelp'
}); });
const auth = authorizations.findAndSplice(auth => auth.pFlags.current); const auth = findAndSplice(authorizations, auth => auth.pFlags.current);
const session = Session(auth); const session = Session(auth);
section.content.append(session.container); section.content.append(session.container);

9
src/components/wrappers.ts

@ -57,6 +57,7 @@ import IS_VIBRATE_SUPPORTED from '../environment/vibrateSupport';
import Row from './row'; import Row from './row';
import { ChatAutoDownloadSettings } from '../helpers/autoDownload'; import { ChatAutoDownloadSettings } from '../helpers/autoDownload';
import formatBytes from '../helpers/formatBytes'; import formatBytes from '../helpers/formatBytes';
import toHHMMSS from '../helpers/string/toHHMMSS';
const MAX_VIDEO_AUTOPLAY_SIZE = 50 * 1024 * 1024; // 50 MB const MAX_VIDEO_AUTOPLAY_SIZE = 50 * 1024 * 1024; // 50 MB
@ -123,7 +124,7 @@ export function wrapVideo({doc, container, message, boxWidth, boxHeight, withTai
let needPlayButton = false; let needPlayButton = false;
if(doc.type !== 'gif') { if(doc.type !== 'gif') {
spanTime.innerText = (doc.duration + '').toHHMMSS(false); spanTime.innerText = toHHMMSS(doc.duration, false);
if(!noPlayButton && doc.type !== 'round') { if(!noPlayButton && doc.type !== 'round') {
if(canAutoplay && !noAutoDownload) { if(canAutoplay && !noAutoDownload) {
@ -266,7 +267,7 @@ export function wrapVideo({doc, container, message, boxWidth, boxHeight, withTai
onFrame(); onFrame();
} }
spanTime.innerText = (globalVideo.duration - globalVideo.currentTime + '').toHHMMSS(false); spanTime.innerText = toHHMMSS(globalVideo.duration - globalVideo.currentTime, false);
}; };
const throttledTimeUpdate = throttleWithRaf(onTimeUpdate); const throttledTimeUpdate = throttleWithRaf(onTimeUpdate);
@ -295,7 +296,7 @@ export function wrapVideo({doc, container, message, boxWidth, boxHeight, withTai
divRound.classList.add('is-paused'); divRound.classList.add('is-paused');
video.currentTime = 0; video.currentTime = 0;
spanTime.innerText = ('' + globalVideo.duration).toHHMMSS(false); spanTime.innerText = toHHMMSS(globalVideo.duration, false);
if(globalVideo.currentTime) { if(globalVideo.currentTime) {
globalVideo.currentTime = 0; globalVideo.currentTime = 0;
@ -451,7 +452,7 @@ export function wrapVideo({doc, container, message, boxWidth, boxHeight, withTai
if(doc.type === 'video') { if(doc.type === 'video') {
video.addEventListener('timeupdate', () => { video.addEventListener('timeupdate', () => {
spanTime.innerText = (video.duration - video.currentTime + '').toHHMMSS(false); spanTime.innerText = toHHMMSS(video.duration - video.currentTime, false);
}); });
if(spanPlay) { if(spanPlay) {

4
src/helpers/array/findAndSplice.ts

@ -0,0 +1,4 @@
export default function findAndSplice<T>(array: Array<T>, verify: (value: T, index?: number, array?: Array<T>) => boolean) {
const index = array.findIndex(verify);
return index !== -1 ? array.splice(index, 1)[0] : undefined;
};

9
src/helpers/array/randomize.ts

@ -0,0 +1,9 @@
export default function randomize<T extends ArrayBufferView>(arr: T) {
if(crypto && 'getRandomValues' in crypto) {
crypto.getRandomValues(arr);
} else {
throw new Error('NO_SECURE_RANDOM');
}
return arr;
}

3
src/helpers/bytes/addPadding.ts

@ -1,3 +1,4 @@
import randomize from "../array/randomize";
import bufferConcats from "./bufferConcats"; import bufferConcats from "./bufferConcats";
export default function addPadding<T extends number[] | ArrayBuffer | Uint8Array>( export default function addPadding<T extends number[] | ArrayBuffer | Uint8Array>(
@ -17,7 +18,7 @@ export default function addPadding<T extends number[] | ArrayBuffer | Uint8Array
padding[i] = 0; padding[i] = 0;
} }
} else { } else {
padding.randomize(); randomize(padding);
} }
if(bytes instanceof ArrayBuffer) { if(bytes instanceof ArrayBuffer) {

3
src/helpers/eventListenerBase.ts

@ -6,6 +6,7 @@
//import { MOUNT_CLASS_TO } from "../config/debug"; //import { MOUNT_CLASS_TO } from "../config/debug";
import type { ArgumentTypes, SuperReturnType } from "../types"; import type { ArgumentTypes, SuperReturnType } from "../types";
import findAndSplice from "./array/findAndSplice";
// class EventSystem { // class EventSystem {
// wm: WeakMap<any, Record<any, Set<any>>> = new WeakMap(); // wm: WeakMap<any, Record<any, Set<any>>> = new WeakMap();
@ -105,7 +106,7 @@ export default class EventListenerBase<Listeners extends EventListenerListeners>
public removeEventListener<T extends keyof Listeners>(name: T, callback: Listeners[T], options?: boolean | AddEventListenerOptions) { public removeEventListener<T extends keyof Listeners>(name: T, callback: Listeners[T], options?: boolean | AddEventListenerOptions) {
if(this.listeners[name]) { if(this.listeners[name]) {
this.listeners[name].findAndSplice(l => l.callback === callback); findAndSplice(this.listeners[name], l => l.callback === callback);
} }
//e.remove(this, name, callback); //e.remove(this, name, callback);
} }

11
src/helpers/string/toHHMMSS.ts

@ -0,0 +1,11 @@
export default function toHHMMSS(str: string | number, leadZero = false) {
const sec_num = parseInt(str + '', 10);
const hours = Math.floor(sec_num / 3600);
let minutes: any = Math.floor((sec_num - (hours * 3600)) / 60);
let seconds: any = sec_num - (hours * 3600) - (minutes * 60);
if(hours) leadZero = true;
if(minutes < 10) minutes = leadZero ? "0" + minutes : minutes;
if(seconds < 10) seconds = "0" + seconds;
return (hours ? /* ('0' + hours).slice(-2) */hours + ':' : '') + minutes + ':' + seconds;
}

3
src/lib/appManagers/appChatsManager.ts

@ -24,6 +24,7 @@ import appPeersManager from "./appPeersManager";
import appStateManager from "./appStateManager"; import appStateManager from "./appStateManager";
import appUsersManager from "./appUsersManager"; import appUsersManager from "./appUsersManager";
import { isRestricted } from "../../helpers/restrictions"; import { isRestricted } from "../../helpers/restrictions";
import findAndSplice from "../../helpers/array/findAndSplice";
export type Channel = Chat.channel; export type Channel = Chat.channel;
export type ChatRights = keyof ChatBannedRights['pFlags'] | keyof ChatAdminRights['pFlags'] | 'change_type' | 'change_permissions' | 'delete_chat' | 'view_participants'; export type ChatRights = keyof ChatBannedRights['pFlags'] | keyof ChatAdminRights['pFlags'] | 'change_type' | 'change_permissions' | 'delete_chat' | 'view_participants';
@ -104,7 +105,7 @@ export class AppChatsManager {
delete this.usernames[cleanUsername(chat.username)]; delete this.usernames[cleanUsername(chat.username)];
} */ } */
chats.findAndSplice((chat) => chat.id === chatId); findAndSplice(chats, (chat) => chat.id === chatId);
this.storage.delete(chatId); this.storage.delete(chatId);
delete this.chats[chatId]; delete this.chats[chatId];
} }

2
src/lib/appManagers/appMessagesManager.ts

@ -5576,7 +5576,7 @@ export class AppMessagesManager {
if(options.userReaction) { if(options.userReaction) {
const langPackKey: LangPackKey = /* isAnyChat ? 'Notification.Group.Reacted' : */'Notification.Contact.Reacted'; const langPackKey: LangPackKey = /* isAnyChat ? 'Notification.Group.Reacted' : */'Notification.Contact.Reacted';
const args: FormatterArguments = [ const args: FormatterArguments = [
options.userReaction.reaction, RichTextProcessor.fixEmoji(options.userReaction.reaction), // can be plain heart
notificationMessage notificationMessage
]; ];

5
src/lib/appManagers/appReactionsManager.ts

@ -5,6 +5,7 @@
*/ */
import { MOUNT_CLASS_TO } from "../../config/debug"; import { MOUNT_CLASS_TO } from "../../config/debug";
import findAndSplice from "../../helpers/array/findAndSplice";
import assumeType from "../../helpers/assumeType"; import assumeType from "../../helpers/assumeType";
import callbackify from "../../helpers/callbackify"; import callbackify from "../../helpers/callbackify";
import callbackifyAll from "../../helpers/callbackifyAll"; import callbackifyAll from "../../helpers/callbackifyAll";
@ -113,7 +114,7 @@ export class AppReactionsManager {
} }
private unshiftQuickReactionInner(availableReactions: AvailableReaction.availableReaction[], quickReaction: AvailableReaction.availableReaction) { private unshiftQuickReactionInner(availableReactions: AvailableReaction.availableReaction[], quickReaction: AvailableReaction.availableReaction) {
const availableReaction = availableReactions.findAndSplice(availableReaction => availableReaction.reaction === quickReaction.reaction); const availableReaction = findAndSplice(availableReactions, availableReaction => availableReaction.reaction === quickReaction.reaction);
if(availableReaction) { if(availableReaction) {
availableReactions.unshift(availableReaction); availableReactions.unshift(availableReaction);
} }
@ -245,7 +246,7 @@ export class AppReactionsManager {
} */ } */
if(reactions.recent_reactions) { if(reactions.recent_reactions) {
reactions.recent_reactions.findAndSplice((recentReaction) => appPeersManager.getPeerId(recentReaction.peer_id) === myPeerId); findAndSplice(reactions.recent_reactions, (recentReaction) => appPeersManager.getPeerId(recentReaction.peer_id) === myPeerId);
} }
if(!reactions.results.length) { if(!reactions.results.length) {

3
src/lib/appManagers/appStickersManager.ts

@ -20,6 +20,7 @@ import assumeType from '../../helpers/assumeType';
import fixBase64String from '../../helpers/fixBase64String'; import fixBase64String from '../../helpers/fixBase64String';
import IS_WEBM_SUPPORTED from '../../environment/webmSupport'; import IS_WEBM_SUPPORTED from '../../environment/webmSupport';
import forEachReverse from '../../helpers/array/forEachReverse'; import forEachReverse from '../../helpers/array/forEachReverse';
import findAndSplice from '../../helpers/array/findAndSplice';
const CACHE_TIME = 3600e3; const CACHE_TIME = 3600e3;
@ -568,7 +569,7 @@ export class AppStickersManager {
for(const emoticon in this.getStickersByEmoticonsPromises) { for(const emoticon in this.getStickersByEmoticonsPromises) {
const promise = this.getStickersByEmoticonsPromises[emoticon]; const promise = this.getStickersByEmoticonsPromises[emoticon];
promise.then(stickers => { promise.then(stickers => {
const _doc = stickers.findAndSplice(_doc => _doc.id === doc.id); const _doc = findAndSplice(stickers, _doc => _doc.id === doc.id);
if(_doc) { if(_doc) {
stickers.unshift(_doc); stickers.unshift(_doc);
} else if(emoticon.includes(docEmoticon)) { } else if(emoticon.includes(docEmoticon)) {

3
src/lib/appManagers/appUsersManager.ts

@ -11,6 +11,7 @@
import { MOUNT_CLASS_TO } from "../../config/debug"; import { MOUNT_CLASS_TO } from "../../config/debug";
import filterUnique from "../../helpers/array/filterUnique"; import filterUnique from "../../helpers/array/filterUnique";
import findAndSplice from "../../helpers/array/findAndSplice";
import indexOfAndSplice from "../../helpers/array/indexOfAndSplice"; import indexOfAndSplice from "../../helpers/array/indexOfAndSplice";
import { CancellablePromise, deferredPromise } from "../../helpers/cancellablePromise"; import { CancellablePromise, deferredPromise } from "../../helpers/cancellablePromise";
import cleanSearchText from "../../helpers/cleanSearchText"; import cleanSearchText from "../../helpers/cleanSearchText";
@ -190,7 +191,7 @@ export class AppUsersManager {
delete this.usernames[cleanUsername(user.username)]; delete this.usernames[cleanUsername(user.username)];
} }
users.findAndSplice((user) => user.id === userId); findAndSplice(users, (user) => user.id === userId);
this.storage.delete(userId); this.storage.delete(userId);
delete this.users[userId]; delete this.users[userId];
} }

3
src/lib/crypto/generateDh.ts

@ -5,6 +5,7 @@
*/ */
import bigInt from "big-integer"; import bigInt from "big-integer";
import randomize from "../../helpers/array/randomize";
import { bigIntFromBytes } from "../../helpers/bigInt/bigIntConversion"; import { bigIntFromBytes } from "../../helpers/bigInt/bigIntConversion";
import addPadding from "../../helpers/bytes/addPadding"; import addPadding from "../../helpers/bytes/addPadding";
import bytesFromHex from "../../helpers/bytes/bytesFromHex"; import bytesFromHex from "../../helpers/bytes/bytesFromHex";
@ -17,7 +18,7 @@ export default async function generateDh(dhConfig: MessagesDhConfig.messagesDhCo
const generateA = (p: Uint8Array) => { const generateA = (p: Uint8Array) => {
for(;;) { for(;;) {
const a = new Uint8Array(p.length).randomize(); const a = randomize(new Uint8Array(p.length));
// const a = new Uint8Array(4).randomize(); // const a = new Uint8Array(4).randomize();
const aBigInt = bigIntFromBytes(a); // str2bigInt(bytesToHex(a), 16); const aBigInt = bigIntFromBytes(a); // str2bigInt(bytesToHex(a), 16);

3
src/lib/crypto/srp.ts

@ -118,7 +118,8 @@ export default async function computeSRP(password: string, state: AccountPasswor
const a_for_hash = bigIntToBytes(A); const a_for_hash = bigIntToBytes(A);
const s = await cryptoWorker.invokeCrypto('sha256', bufferConcats(a_for_hash, b_for_hash)); const s = await cryptoWorker.invokeCrypto('sha256', bufferConcats(a_for_hash, b_for_hash));
const u = bigInt(s.hex, 16); // const u = bigInt(s.hex, 16);
const u = bigIntFromBytes(s);
if(!u.isZero() && !u.isNegative()) if(!u.isZero() && !u.isNegative())
return {a, a_for_hash, u}; return {a, a_for_hash, u};
} }

9
src/lib/mediaPlayer.ts

@ -18,6 +18,7 @@ import { GrabEvent } from "../helpers/dom/attachGrabListeners";
import { attachClickEvent } from "../helpers/dom/clickEvent"; import { attachClickEvent } from "../helpers/dom/clickEvent";
import ControlsHover from "../helpers/dom/controlsHover"; import ControlsHover from "../helpers/dom/controlsHover";
import { addFullScreenListener, cancelFullScreen, isFullScreen, requestFullScreen } from "../helpers/dom/fullScreen"; import { addFullScreenListener, cancelFullScreen, isFullScreen, requestFullScreen } from "../helpers/dom/fullScreen";
import toHHMMSS from "../helpers/string/toHHMMSS";
export class MediaProgressLine extends RangeSelector { export class MediaProgressLine extends RangeSelector {
protected filledLoad: HTMLDivElement; protected filledLoad: HTMLDivElement;
@ -351,7 +352,7 @@ export default class VideoPlayer extends ControlsHover {
const fullScreenButton = wrapper.querySelector('.fullscreen') as HTMLElement; const fullScreenButton = wrapper.querySelector('.fullscreen') as HTMLElement;
const timeElapsed = wrapper.querySelector('#time-elapsed'); const timeElapsed = wrapper.querySelector('#time-elapsed');
timeDuration = wrapper.querySelector('#time-duration') as HTMLElement; timeDuration = wrapper.querySelector('#time-duration') as HTMLElement;
timeDuration.innerHTML = String(video.duration | 0).toHHMMSS(); timeDuration.innerHTML = toHHMMSS(video.duration | 0);
const volumeSelector = new VolumeSelector(listenerSetter); const volumeSelector = new VolumeSelector(listenerSetter);
@ -430,7 +431,7 @@ export default class VideoPlayer extends ControlsHover {
addFullScreenListener(wrapper, this.onFullScreen.bind(this, fullScreenButton), listenerSetter); addFullScreenListener(wrapper, this.onFullScreen.bind(this, fullScreenButton), listenerSetter);
listenerSetter.add(video)('timeupdate', () => { listenerSetter.add(video)('timeupdate', () => {
timeElapsed.innerHTML = String(video.currentTime | 0).toHHMMSS(); timeElapsed.innerHTML = toHHMMSS(video.currentTime | 0);
}); });
listenerSetter.add(video)('play', () => { listenerSetter.add(video)('play', () => {
@ -461,10 +462,10 @@ export default class VideoPlayer extends ControlsHover {
}); });
if(video.duration || initDuration) { if(video.duration || initDuration) {
timeDuration.innerHTML = String(Math.round(video.duration || initDuration)).toHHMMSS(); timeDuration.innerHTML = toHHMMSS(Math.round(video.duration || initDuration));
} else { } else {
onMediaLoad(video).then(() => { onMediaLoad(video).then(() => {
timeDuration.innerHTML = String(Math.round(video.duration)).toHHMMSS(); timeDuration.innerHTML = toHHMMSS(Math.round(video.duration));
}); });
} }
} }

5
src/lib/mtproto/apiFileManager.ts

@ -29,6 +29,7 @@ import ctx from "../../environment/ctx";
import noop from "../../helpers/noop"; import noop from "../../helpers/noop";
import readBlobAsArrayBuffer from "../../helpers/blob/readBlobAsArrayBuffer"; import readBlobAsArrayBuffer from "../../helpers/blob/readBlobAsArrayBuffer";
import bytesToHex from "../../helpers/bytes/bytesToHex"; import bytesToHex from "../../helpers/bytes/bytesToHex";
import findAndSplice from "../../helpers/array/findAndSplice";
type Delayed = { type Delayed = {
offset: number, offset: number,
@ -145,7 +146,7 @@ export class ApiFileManager {
} }
//const data = downloadPull.shift(); //const data = downloadPull.shift();
const data = downloadPull.findAndSplice(d => d.queueId === 0) || downloadPull.findAndSplice(d => d.queueId === this.queueId) || downloadPull.shift(); const data = findAndSplice(downloadPull, d => d.queueId === 0) || findAndSplice(downloadPull, d => d.queueId === this.queueId) || downloadPull.shift();
const activeDelta = data.activeDelta || 1; const activeDelta = data.activeDelta || 1;
this.downloadActives[dcId] += activeDelta; this.downloadActives[dcId] += activeDelta;
@ -521,7 +522,7 @@ export class ApiFileManager {
this.cachedDownloadPromises[fileName] = deferred; this.cachedDownloadPromises[fileName] = deferred;
deferred.safeFinally(() => { deferred.catch(noop).finally(() => {
delete this.cachedDownloadPromises[fileName]; delete this.cachedDownloadPromises[fileName];
}); });

11
src/lib/mtproto/authorizer.ts

@ -31,6 +31,7 @@ import bytesToHex from "../../helpers/bytes/bytesToHex";
import bytesXor from "../../helpers/bytes/bytesXor"; import bytesXor from "../../helpers/bytes/bytesXor";
import { bigIntFromBytes } from "../../helpers/bigInt/bigIntConversion"; import { bigIntFromBytes } from "../../helpers/bigInt/bigIntConversion";
import bigInt from "big-integer"; import bigInt from "big-integer";
import randomize from "../../helpers/array/randomize";
/* let fNewNonce: any = bytesFromHex('8761970c24cb2329b5b2459752c502f3057cb7e8dbab200e526e8767fdc73b3c').reverse(); /* let fNewNonce: any = bytesFromHex('8761970c24cb2329b5b2459752c502f3057cb7e8dbab200e526e8767fdc73b3c').reverse();
let fNonce: any = bytesFromHex('b597720d11faa5914ef485c529cde414').reverse(); let fNonce: any = bytesFromHex('b597720d11faa5914ef485c529cde414').reverse();
@ -200,7 +201,7 @@ export class Authorizer {
request.storeMethod('req_pq_multi', {nonce: auth.nonce}); request.storeMethod('req_pq_multi', {nonce: auth.nonce});
if(DEBUG) { if(DEBUG) {
this.log('Send req_pq', auth.nonce.hex); this.log('Send req_pq', bytesToHex(auth.nonce));
} }
let deserializer: Awaited<ReturnType<Authorizer['sendPlainRequest']>>; let deserializer: Awaited<ReturnType<Authorizer['sendPlainRequest']>>;
@ -262,7 +263,7 @@ export class Authorizer {
} }
private async sendReqDhParams(auth: AuthOptions): Promise<AuthOptions> { private async sendReqDhParams(auth: AuthOptions): Promise<AuthOptions> {
auth.newNonce = new Uint8Array(32).randomize(); auth.newNonce = randomize(new Uint8Array(32));
const p_q_inner_data_dc: P_Q_inner_data = { const p_q_inner_data_dc: P_Q_inner_data = {
_: 'p_q_inner_data_dc', _: 'p_q_inner_data_dc',
@ -288,7 +289,7 @@ export class Authorizer {
const getKeyAesEncrypted = async() => { const getKeyAesEncrypted = async() => {
for(;;) { for(;;) {
const tempKey = new Uint8Array(32).randomize(); const tempKey = randomize(new Uint8Array(32));
const dataWithHash = dataPadReversed.concat(await CryptoWorker.invokeCrypto('sha256', tempKey.concat(dataWithPadding))); const dataWithHash = dataPadReversed.concat(await CryptoWorker.invokeCrypto('sha256', tempKey.concat(dataWithPadding)));
if(dataWithHash.length !== 224) { if(dataWithHash.length !== 224) {
throw 'DH_params: dataWithHash !== 224 bytes!'; throw 'DH_params: dataWithHash !== 224 bytes!';
@ -475,7 +476,7 @@ export class Authorizer {
private async sendSetClientDhParams(auth: AuthOptions): Promise<AuthOptions> { private async sendSetClientDhParams(auth: AuthOptions): Promise<AuthOptions> {
const gBytes = bytesFromHex(auth.g.toString(16)); const gBytes = bytesFromHex(auth.g.toString(16));
auth.b = new Uint8Array(256).randomize(); auth.b = randomize(new Uint8Array(256));
//MTProto.secureRandom.nextBytes(auth.b); //MTProto.secureRandom.nextBytes(auth.b);
// let gB: Awaited<ReturnType<typeof CryptoWorker['modPow']>>; // let gB: Awaited<ReturnType<typeof CryptoWorker['modPow']>>;
@ -611,7 +612,7 @@ export class Authorizer {
try { try {
const auth: AuthOptions = { const auth: AuthOptions = {
dcId, dcId,
nonce: new Uint8Array(16).randomize() nonce: randomize(new Uint8Array(16))
}; };
const promise = this.sendReqPQ(auth); const promise = this.sendReqPQ(auth);

7
src/lib/mtproto/networker.ts

@ -40,6 +40,7 @@ import convertToUint8Array from '../../helpers/bytes/convertToUint8Array';
import isObject from '../../helpers/object/isObject'; import isObject from '../../helpers/object/isObject';
import forEachReverse from '../../helpers/array/forEachReverse'; import forEachReverse from '../../helpers/array/forEachReverse';
import sortLongsArray from '../../helpers/long/sortLongsArray'; import sortLongsArray from '../../helpers/long/sortLongsArray';
import randomize from '../../helpers/array/randomize';
//console.error('networker included!', new Error().stack); //console.error('networker included!', new Error().stack);
@ -193,7 +194,7 @@ export default class MTPNetworker {
private updateSession() { private updateSession() {
this.seqNo = 0; this.seqNo = 0;
this.prevSessionId = this.sessionId; this.prevSessionId = this.sessionId;
this.sessionId = new Uint8Array(8).randomize(); this.sessionId = randomize(new Uint8Array(8));
} }
/* private clearContainers() { /* private clearContainers() {
@ -1149,7 +1150,7 @@ export default class MTPNetworker {
} */ } */
const paddingLength = (16 - (data.getOffset() % 16)) + 16 * (1 + nextRandomUint(8) % 5); const paddingLength = (16 - (data.getOffset() % 16)) + 16 * (1 + nextRandomUint(8) % 5);
const padding = /* (message as any).padding || */new Uint8Array(paddingLength).randomize()/* .fill(0) */; const padding = /* (message as any).padding || */randomize(new Uint8Array(paddingLength))/* .fill(0) */;
/* const padding = [167, 148, 207, 226, 86, 192, 193, 57, 124, 153, 174, 145, 159, 1, 5, 70, 127, 157, /* const padding = [167, 148, 207, 226, 86, 192, 193, 57, 124, 153, 174, 145, 159, 1, 5, 70, 127, 157,
51, 241, 46, 85, 141, 212, 139, 234, 213, 164, 197, 116, 245, 70, 184, 40, 40, 201, 233, 211, 150, 51, 241, 46, 85, 141, 212, 139, 234, 213, 164, 197, 116, 245, 70, 184, 40, 40, 201, 233, 211, 150,
94, 57, 84, 1, 135, 108, 253, 34, 139, 222, 208, 71, 214, 90, 67, 36, 28, 167, 148, 207, 226, 86, 192, 193, 57, 124, 153, 174, 145, 159, 1, 5, 70, 127, 157, 94, 57, 84, 1, 135, 108, 253, 34, 139, 222, 208, 71, 214, 90, 67, 36, 28, 167, 148, 207, 226, 86, 192, 193, 57, 124, 153, 174, 145, 159, 1, 5, 70, 127, 157,
@ -1249,7 +1250,7 @@ export default class MTPNetworker {
const authKeyId = deserializer.fetchIntBytes(64, true, 'auth_key_id'); const authKeyId = deserializer.fetchIntBytes(64, true, 'auth_key_id');
if(!bytesCmp(authKeyId, this.authKeyId)) { if(!bytesCmp(authKeyId, this.authKeyId)) {
throw new Error('[MT] Invalid server auth_key_id: ' + authKeyId.hex); throw new Error('[MT] Invalid server auth_key_id: ' + bytesToHex(authKeyId));
} }
const msgKey = deserializer.fetchIntBytes(128, true, 'msg_key'); const msgKey = deserializer.fetchIntBytes(128, true, 'msg_key');

3
src/lib/mtproto/passwordManager.ts

@ -12,6 +12,7 @@
import type { AccountPassword, AccountUpdatePasswordSettings, InputCheckPasswordSRP, PasswordKdfAlgo } from '../../layer'; import type { AccountPassword, AccountUpdatePasswordSettings, InputCheckPasswordSRP, PasswordKdfAlgo } from '../../layer';
import { MOUNT_CLASS_TO } from '../../config/debug'; import { MOUNT_CLASS_TO } from '../../config/debug';
import apiManager from './mtprotoworker'; import apiManager from './mtprotoworker';
import randomize from '../../helpers/array/randomize';
export class PasswordManager { export class PasswordManager {
public getState(): Promise<AccountPassword> { public getState(): Promise<AccountPassword> {
@ -52,7 +53,7 @@ export class PasswordManager {
// * https://core.telegram.org/api/srp#setting-a-new-2fa-password, but still there is a mistake, TDesktop passes 'new_algo' everytime // * https://core.telegram.org/api/srp#setting-a-new-2fa-password, but still there is a mistake, TDesktop passes 'new_algo' everytime
const newAlgo = state.new_algo as PasswordKdfAlgo.passwordKdfAlgoSHA256SHA256PBKDF2HMACSHA512iter100000SHA256ModPow; const newAlgo = state.new_algo as PasswordKdfAlgo.passwordKdfAlgoSHA256SHA256PBKDF2HMACSHA512iter100000SHA256ModPow;
const salt1 = new Uint8Array(newAlgo.salt1.length + 32); const salt1 = new Uint8Array(newAlgo.salt1.length + 32);
salt1.randomize(); randomize(salt1);
salt1.set(newAlgo.salt1, 0); salt1.set(newAlgo.salt1, 0);
newAlgo.salt1 = salt1; newAlgo.salt1 = salt1;

2
src/lib/mtproto/tl_utils.ts

@ -484,7 +484,7 @@ class TLDeserialization<FetchLongAs extends Long> {
this.debug/* || field.includes('[dialog][read_outbox_max_id]') */ this.debug/* || field.includes('[dialog][read_outbox_max_id]') */
&& console.log('<<<', i.toString(16), i, field, && console.log('<<<', i.toString(16), i, field,
this.byteView.slice(this.offset - 16, this.offset + 16), this.byteView.slice(this.offset - 16, this.offset + 16),
this.byteView.slice(this.offset - 16, this.offset + 16).hex); bytesToHex(this.byteView.slice(this.offset - 16, this.offset + 16)));
this.offset += 4; this.offset += 4;

5
src/lib/mtproto/transports/obfuscation.ts

@ -6,6 +6,7 @@
//import aesjs from 'aes-js'; //import aesjs from 'aes-js';
import AES from "@cryptography/aes"; import AES from "@cryptography/aes";
import randomize from "../../../helpers/array/randomize";
import bytesFromWordss from "../../../helpers/bytes/bytesFromWordss"; import bytesFromWordss from "../../../helpers/bytes/bytesFromWordss";
import { Codec } from "./codec"; import { Codec } from "./codec";
@ -72,7 +73,7 @@ export default class Obfuscation {
public /* async */ init(codec: Codec) { public /* async */ init(codec: Codec) {
const initPayload = new Uint8Array(64); const initPayload = new Uint8Array(64);
initPayload.randomize(); randomize(initPayload);
while(true) { while(true) {
const val = (initPayload[3] << 24) | (initPayload[2] << 16) | (initPayload[1] << 8) | initPayload[0]; const val = (initPayload[3] << 24) | (initPayload[2] << 16) | (initPayload[1] << 8) | initPayload[0];
@ -88,7 +89,7 @@ export default class Obfuscation {
//initPayload[56] = initPayload[57] = initPayload[58] = initPayload[59] = transport; //initPayload[56] = initPayload[57] = initPayload[58] = initPayload[59] = transport;
break; break;
} }
initPayload.randomize(); randomize(initPayload);
} }
////////////////////////initPayload.subarray(60, 62).hex = dcId; ////////////////////////initPayload.subarray(60, 62).hex = dcId;

3
src/lib/mtproto/transports/padded.ts

@ -4,6 +4,7 @@
* https://github.com/morethanwords/tweb/blob/master/LICENSE * https://github.com/morethanwords/tweb/blob/master/LICENSE
*/ */
import randomize from "../../../helpers/array/randomize";
import { nextRandomUint } from "../../../helpers/random"; import { nextRandomUint } from "../../../helpers/random";
import { IntermediatePacketCodec } from "./intermediate"; import { IntermediatePacketCodec } from "./intermediate";
/* Data packets are aligned to 4bytes. This codec adds random bytes of size /* Data packets are aligned to 4bytes. This codec adds random bytes of size
@ -13,7 +14,7 @@ class PaddedIntermediatePacketCodec extends IntermediatePacketCodec {
public obfuscateTag = new Uint8Array([this.tag, this.tag, this.tag, this.tag]); public obfuscateTag = new Uint8Array([this.tag, this.tag, this.tag, this.tag]);
public encodePacket(data: Uint8Array) { public encodePacket(data: Uint8Array) {
let padding = new Uint8Array(nextRandomUint(8) % 3).randomize(); let padding = randomize(new Uint8Array(nextRandomUint(8) % 3));
let len = data.byteLength + padding.byteLength; let len = data.byteLength + padding.byteLength;
let header = new Uint8Array(new Uint32Array([len]).buffer); let header = new Uint8Array(new Uint32Array([len]).buffer);

3
src/lib/mtproto/transports/tcpObfuscated.ts

@ -14,6 +14,7 @@ import { ConnectionStatus } from "../connectionStatus";
/// #if MTPROTO_AUTO /// #if MTPROTO_AUTO
import transportController from "./controller"; import transportController from "./controller";
import bytesToHex from "../../../helpers/bytes/bytesToHex";
/// #endif /// #endif
export default class TcpObfuscated implements MTTransport { export default class TcpObfuscated implements MTTransport {
@ -112,7 +113,7 @@ export default class TcpObfuscated implements MTTransport {
//console.log('got hex:', data.hex); //console.log('got hex:', data.hex);
const pending = this.pending.shift(); const pending = this.pending.shift();
if(!pending) { if(!pending) {
this.debug && this.log.debug('no pending for res:', data.hex); this.debug && this.log.debug('no pending for res:', bytesToHex(data));
return; return;
} }

65
src/lib/polyfill.ts

@ -5,30 +5,6 @@
*/ */
import bufferConcats from "../helpers/bytes/bufferConcats"; import bufferConcats from "../helpers/bytes/bufferConcats";
import bytesFromHex from "../helpers/bytes/bytesFromHex";
import bytesToHex from "../helpers/bytes/bytesToHex";
Object.defineProperty(Uint8Array.prototype, 'hex', {
get: function(): string {
return bytesToHex(this);
},
set: function(str: string) {
this.set(bytesFromHex(str));
},
enumerable: true,
configurable: true
});
Uint8Array.prototype.randomize = function() {
if(crypto && 'getRandomValues' in crypto) {
crypto.getRandomValues(this);
} else {
throw new Error('NO_SECURE_RANDOM');
}
return this;
};
Uint8Array.prototype.concat = function(...args: Array<Uint8Array | ArrayBuffer | number[]>) { Uint8Array.prototype.concat = function(...args: Array<Uint8Array | ArrayBuffer | number[]>) {
return bufferConcats(this, ...args); return bufferConcats(this, ...args);
@ -43,32 +19,6 @@ Uint8Array.prototype.toJSON = function() {
//return {type: 'bytes', value: [...this]}; //return {type: 'bytes', value: [...this]};
}; };
Array.prototype.findAndSplice = function<T>(verify: (value: T, index?: number, array?: Array<T>) => boolean) {
let index = this.findIndex(verify);
return index !== -1 ? this.splice(index, 1)[0] : undefined;
};
String.prototype.toHHMMSS = function(leadZero = false) {
const sec_num = parseInt(this + '', 10);
const hours = Math.floor(sec_num / 3600);
let minutes: any = Math.floor((sec_num - (hours * 3600)) / 60);
let seconds: any = sec_num - (hours * 3600) - (minutes * 60);
if(hours) leadZero = true;
if(minutes < 10) minutes = leadZero ? "0" + minutes : minutes;
if(seconds < 10) seconds = "0" + seconds;
return (hours ? /* ('0' + hours).slice(-2) */hours + ':' : '') + minutes + ':' + seconds;
};
/* Promise.prototype.finally = Promise.prototype.finally || {
finally(fn: () => any) {
const onFinally = (callback: typeof fn) => Promise.resolve(fn()).then(callback);
return this.then(
result => onFinally(() => result),
reason => onFinally(() => Promise.reject(reason))
);
}
}.finally; */
Promise.prototype.finally = Promise.prototype.finally || function<T>(this: Promise<T>, fn: () => any) { Promise.prototype.finally = Promise.prototype.finally || function<T>(this: Promise<T>, fn: () => any) {
const onFinally = (callback: typeof fn) => Promise.resolve(fn()).then(callback); const onFinally = (callback: typeof fn) => Promise.resolve(fn()).then(callback);
return this.then( return this.then(
@ -77,30 +27,15 @@ Promise.prototype.finally = Promise.prototype.finally || function<T>(this: Promi
); );
}; };
Promise.prototype.safeFinally = function<T>(this: Promise<T>, fn: () => any) {
return this.catch(() => {}).finally(fn);
};
declare global { declare global {
interface Uint8Array { interface Uint8Array {
hex: string;
randomize: () => Uint8Array,
concat: (...args: Array<Uint8Array | ArrayBuffer | number[]>) => Uint8Array, concat: (...args: Array<Uint8Array | ArrayBuffer | number[]>) => Uint8Array,
//toString: () => string, //toString: () => string,
toJSON: () => number[], toJSON: () => number[],
//toJSON: () => {type: 'bytes', value: number[]}, //toJSON: () => {type: 'bytes', value: number[]},
} }
interface Array<T> {
findAndSplice(verify: (value: T, index?: number, array?: Array<T>) => boolean): T;
}
interface String {
toHHMMSS(leadZero?: boolean): string;
}
interface Promise<T> { interface Promise<T> {
finally: (onfinally?: () => void) => Promise<T>; finally: (onfinally?: () => void) => Promise<T>;
safeFinally: (onfinally?: () => void) => Promise<T>;
} }
} }

Loading…
Cancel
Save