* refactored blockmetadata
* be more careful with block type length + work on chat
This commit is contained in:
		
							parent
							
								
									8c7319048d
								
							
						
					
					
						commit
						7c02f6fff1
					
				
					 15 changed files with 203 additions and 125 deletions
				
			
		|  | @ -27,6 +27,8 @@ API_VERSION = '0' # increments of 1; only change when something fundamental abou | ||||||
| MIN_PY_VERSION = 6 | MIN_PY_VERSION = 6 | ||||||
| DEVELOPMENT_MODE = True | DEVELOPMENT_MODE = True | ||||||
| 
 | 
 | ||||||
|  | MAX_BLOCK_TYPE_LENGTH = 15 | ||||||
|  | 
 | ||||||
| platform = platform.system() | platform = platform.system() | ||||||
| if platform == 'Windows': | if platform == 'Windows': | ||||||
|     SCRIPT_NAME = 'run-windows.bat' |     SCRIPT_NAME = 'run-windows.bat' | ||||||
|  |  | ||||||
|  | @ -54,7 +54,7 @@ class ClientAPISecurity: | ||||||
|         def after_req(resp): |         def after_req(resp): | ||||||
|             # Security headers |             # Security headers | ||||||
|             resp = httpheaders.set_default_onionr_http_headers(resp) |             resp = httpheaders.set_default_onionr_http_headers(resp) | ||||||
|             if request.endpoint == 'site': |             if request.endpoint == 'siteapi.site': | ||||||
|                 resp.headers['Content-Security-Policy'] = "default-src 'none'; style-src data: 'unsafe-inline'; img-src data:" |                 resp.headers['Content-Security-Policy'] = "default-src 'none'; style-src data: 'unsafe-inline'; img-src data:" | ||||||
|             else: |             else: | ||||||
|                 resp.headers['Content-Security-Policy'] = "default-src 'none'; script-src 'self'; object-src 'none'; style-src 'self'; img-src 'self'; media-src 'none'; frame-src 'none'; font-src 'none'; connect-src 'self'" |                 resp.headers['Content-Security-Policy'] = "default-src 'none'; script-src 'self'; object-src 'none'; style-src 'self'; img-src 'self'; media-src 'none'; frame-src 'none'; font-src 'none'; connect-src 'self'" | ||||||
|  |  | ||||||
|  | @ -42,11 +42,11 @@ def add_file(singleBlock=False, blockType='bin'): | ||||||
|         logger.info('Adding file... this might take a long time.', terminal=True) |         logger.info('Adding file... this might take a long time.', terminal=True) | ||||||
|         try: |         try: | ||||||
|             with open(filename, 'rb') as singleFile: |             with open(filename, 'rb') as singleFile: | ||||||
|                 blockhash = insert.insert_block(base64.b64encode(singleFile.read()), header=blockType) |                 blockhash = insert(base64.b64encode(singleFile.read()), header=blockType) | ||||||
|             if len(blockhash) > 0: |             if len(blockhash) > 0: | ||||||
|                 logger.info('File %s saved in block %s' % (filename, blockhash), terminal=True) |                 logger.info('File %s saved in block %s' % (filename, blockhash), terminal=True) | ||||||
|         except: |         except Exception as e: | ||||||
|             logger.error('Failed to save file in block.', timestamp = False, terminal=True) |             logger.error('Failed to save file in block ' + str(e), timestamp = False, terminal=True) | ||||||
|     else: |     else: | ||||||
|         logger.error('%s add-file <filename>' % sys.argv[0], timestamp = False, terminal=True) |         logger.error('%s add-file <filename>' % sys.argv[0], timestamp = False, terminal=True) | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
							
								
								
									
										24
									
								
								onionr/onionrutils/blockmetadata/__init__.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								onionr/onionrutils/blockmetadata/__init__.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,24 @@ | ||||||
|  | ''' | ||||||
|  |     Onionr - Private P2P Communication | ||||||
|  | 
 | ||||||
|  |     Module to work with block metadata | ||||||
|  | ''' | ||||||
|  | ''' | ||||||
|  |     This program is free software: you can redistribute it and/or modify | ||||||
|  |     it under the terms of the GNU General Public License as published by | ||||||
|  |     the Free Software Foundation, either version 3 of the License, or | ||||||
|  |     (at your option) any later version. | ||||||
|  | 
 | ||||||
|  |     This program is distributed in the hope that it will be useful, | ||||||
|  |     but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  |     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||||
|  |     GNU General Public License for more details. | ||||||
|  | 
 | ||||||
|  |     You should have received a copy of the GNU General Public License | ||||||
|  |     along with this program.  If not, see <https://www.gnu.org/licenses/>. | ||||||
|  | ''' | ||||||
|  | 
 | ||||||
|  | from . import hasblock, fromdata, process | ||||||
|  | has_block = hasblock.has_block | ||||||
|  | process_block_metadata = process.process_block_metadata | ||||||
|  | get_block_metadata_from_data = fromdata.get_block_metadata_from_data | ||||||
							
								
								
									
										49
									
								
								onionr/onionrutils/blockmetadata/fromdata.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								onionr/onionrutils/blockmetadata/fromdata.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,49 @@ | ||||||
|  | ''' | ||||||
|  |     Onionr - Private P2P Communication | ||||||
|  | 
 | ||||||
|  |     Return a useful tuple of (metadata (header), meta, and data) by accepting raw block data | ||||||
|  | ''' | ||||||
|  | ''' | ||||||
|  |     This program is free software: you can redistribute it and/or modify | ||||||
|  |     it under the terms of the GNU General Public License as published by | ||||||
|  |     the Free Software Foundation, either version 3 of the License, or | ||||||
|  |     (at your option) any later version. | ||||||
|  | 
 | ||||||
|  |     This program is distributed in the hope that it will be useful, | ||||||
|  |     but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  |     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||||
|  |     GNU General Public License for more details. | ||||||
|  | 
 | ||||||
|  |     You should have received a copy of the GNU General Public License | ||||||
|  |     along with this program.  If not, see <https://www.gnu.org/licenses/>. | ||||||
|  | ''' | ||||||
|  | 
 | ||||||
|  | import json | ||||||
|  | def get_block_metadata_from_data(block_data): | ||||||
|  |     ''' | ||||||
|  |         accepts block contents as string, returns a tuple of  | ||||||
|  |         metadata, meta (meta being internal metadata, which will be  | ||||||
|  |         returned as an encrypted base64 string if it is encrypted, dict if not). | ||||||
|  |     ''' | ||||||
|  |     meta = {} | ||||||
|  |     metadata = {} | ||||||
|  |     data = block_data | ||||||
|  |     try: | ||||||
|  |         block_data = block_data.encode() | ||||||
|  |     except AttributeError: | ||||||
|  |         pass | ||||||
|  | 
 | ||||||
|  |     try: | ||||||
|  |         metadata = json.loads(block_data[:block_data.find(b'\n')].decode()) | ||||||
|  |     except json.decoder.JSONDecodeError: | ||||||
|  |         pass | ||||||
|  |     else: | ||||||
|  |         data = block_data[block_data.find(b'\n'):].decode() | ||||||
|  | 
 | ||||||
|  |         if not metadata['encryptType'] in ('asym', 'sym'): | ||||||
|  |             try: | ||||||
|  |                 meta = json.loads(metadata['meta']) | ||||||
|  |             except KeyError: | ||||||
|  |                 pass | ||||||
|  |         meta = metadata['meta'] | ||||||
|  |     return (metadata, meta, data) | ||||||
							
								
								
									
										42
									
								
								onionr/onionrutils/blockmetadata/hasblock.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								onionr/onionrutils/blockmetadata/hasblock.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,42 @@ | ||||||
|  | ''' | ||||||
|  |     Onionr - Private P2P Communication | ||||||
|  | 
 | ||||||
|  |     Returns a bool if a block is in the block metadata db or not | ||||||
|  | ''' | ||||||
|  | ''' | ||||||
|  |     This program is free software: you can redistribute it and/or modify | ||||||
|  |     it under the terms of the GNU General Public License as published by | ||||||
|  |     the Free Software Foundation, either version 3 of the License, or | ||||||
|  |     (at your option) any later version. | ||||||
|  | 
 | ||||||
|  |     This program is distributed in the hope that it will be useful, | ||||||
|  |     but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  |     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||||
|  |     GNU General Public License for more details. | ||||||
|  | 
 | ||||||
|  |     You should have received a copy of the GNU General Public License | ||||||
|  |     along with this program.  If not, see <https://www.gnu.org/licenses/>. | ||||||
|  | ''' | ||||||
|  | import sqlite3 | ||||||
|  | from coredb import dbfiles | ||||||
|  | import onionrexceptions | ||||||
|  | from .. import stringvalidators | ||||||
|  | 
 | ||||||
|  | def has_block(hash: str) -> bool: | ||||||
|  |     ''' | ||||||
|  |         Check for new block in the block meta db | ||||||
|  |     ''' | ||||||
|  |     conn = sqlite3.connect(dbfiles.block_meta_db) | ||||||
|  |     c = conn.cursor() | ||||||
|  |     if not stringvalidators.validate_hash(hash): | ||||||
|  |         raise onionrexceptions.InvalidHexHash("Invalid hash") | ||||||
|  |     for result in c.execute("SELECT COUNT() FROM hashes WHERE hash = ?", (hash,)): | ||||||
|  |         if result[0] >= 1: | ||||||
|  |             conn.commit() | ||||||
|  |             conn.close() | ||||||
|  |             return True | ||||||
|  |         else: | ||||||
|  |             conn.commit() | ||||||
|  |             conn.close() | ||||||
|  |             return False | ||||||
|  |     return False | ||||||
|  | @ -1,7 +1,7 @@ | ||||||
| ''' | ''' | ||||||
|     Onionr - Private P2P Communication |     Onionr - Private P2P Communication | ||||||
| 
 | 
 | ||||||
|     Module to fetch block metadata from raw block data and process it |     Process block metadata with relevant actions | ||||||
| ''' | ''' | ||||||
| ''' | ''' | ||||||
|     This program is free software: you can redistribute it and/or modify |     This program is free software: you can redistribute it and/or modify | ||||||
|  | @ -17,45 +17,19 @@ | ||||||
|     You should have received a copy of the GNU General Public License |     You should have received a copy of the GNU General Public License | ||||||
|     along with this program.  If not, see <https://www.gnu.org/licenses/>. |     along with this program.  If not, see <https://www.gnu.org/licenses/>. | ||||||
| ''' | ''' | ||||||
| import json, sqlite3 | 
 | ||||||
| import logger, onionrevents |  | ||||||
| from onionrusers import onionrusers |  | ||||||
| from etc import onionrvalues | from etc import onionrvalues | ||||||
| import onionrblockapi | import onionrblockapi | ||||||
| from . import epoch, stringvalidators, bytesconverter | from .. import epoch, bytesconverter | ||||||
| from coredb import dbfiles, blockmetadb | from coredb import blockmetadb | ||||||
| def get_block_metadata_from_data(blockData): | import logger | ||||||
|     ''' | import onionrevents | ||||||
|         accepts block contents as string, returns a tuple of  |  | ||||||
|         metadata, meta (meta being internal metadata, which will be  |  | ||||||
|         returned as an encrypted base64 string if it is encrypted, dict if not). |  | ||||||
|     ''' |  | ||||||
|     meta = {} |  | ||||||
|     metadata = {} |  | ||||||
|     data = blockData |  | ||||||
|     try: |  | ||||||
|         blockData = blockData.encode() |  | ||||||
|     except AttributeError: |  | ||||||
|         pass |  | ||||||
| 
 | 
 | ||||||
|     try: | def process_block_metadata(blockHash: str): | ||||||
|         metadata = json.loads(blockData[:blockData.find(b'\n')].decode()) |  | ||||||
|     except json.decoder.JSONDecodeError: |  | ||||||
|         pass |  | ||||||
|     else: |  | ||||||
|         data = blockData[blockData.find(b'\n'):].decode() |  | ||||||
| 
 |  | ||||||
|         if not metadata['encryptType'] in ('asym', 'sym'): |  | ||||||
|             try: |  | ||||||
|                 meta = json.loads(metadata['meta']) |  | ||||||
|             except KeyError: |  | ||||||
|                 pass |  | ||||||
|         meta = metadata['meta'] |  | ||||||
|     return (metadata, meta, data) |  | ||||||
| 
 |  | ||||||
| def process_block_metadata(blockHash): |  | ||||||
|     ''' |     ''' | ||||||
|         Read metadata from a block and cache it to the block database |         Read metadata from a block and cache it to the block database | ||||||
|  |          | ||||||
|  |         blockHash -> sha3_256 hex formatted hash of Onionr block | ||||||
|     ''' |     ''' | ||||||
|     curTime = epoch.get_rounded_epoch(roundS=60) |     curTime = epoch.get_rounded_epoch(roundS=60) | ||||||
|     myBlock = onionrblockapi.Block(blockHash) |     myBlock = onionrblockapi.Block(blockHash) | ||||||
|  | @ -67,10 +41,13 @@ def process_block_metadata(blockHash): | ||||||
|         signer = bytesconverter.bytes_to_str(myBlock.signer) |         signer = bytesconverter.bytes_to_str(myBlock.signer) | ||||||
|         valid = myBlock.verifySig() |         valid = myBlock.verifySig() | ||||||
|         if myBlock.getMetadata('newFSKey') is not None: |         if myBlock.getMetadata('newFSKey') is not None: | ||||||
|  |             try: | ||||||
|                 onionrusers.OnionrUser(signer).addForwardKey(myBlock.getMetadata('newFSKey')) |                 onionrusers.OnionrUser(signer).addForwardKey(myBlock.getMetadata('newFSKey')) | ||||||
|  |             except onionrexceptions.InvalidPubkey: | ||||||
|  |                 logger.warn('%s has invalid forward secrecy key to add: %s' % (signer, myBlock.getMetadata('newFSKey'))) | ||||||
|              |              | ||||||
|         try: |         try: | ||||||
|             if len(blockType) <= 10: |             if len(blockType) <= onionrvalues.MAX_BLOCK_TYPE_LENGTH: | ||||||
|                 blockmetadb.update_block_info(blockHash, 'dataType', blockType) |                 blockmetadb.update_block_info(blockHash, 'dataType', blockType) | ||||||
|         except TypeError: |         except TypeError: | ||||||
|             logger.warn("Missing block information") |             logger.warn("Missing block information") | ||||||
|  | @ -83,27 +60,4 @@ def process_block_metadata(blockHash): | ||||||
|             expireTime = onionrvalues.OnionrValues().default_expire + curTime |             expireTime = onionrvalues.OnionrValues().default_expire + curTime | ||||||
|         finally: |         finally: | ||||||
|             blockmetadb.update_block_info(blockHash, 'expire', expireTime) |             blockmetadb.update_block_info(blockHash, 'expire', expireTime) | ||||||
|         if not blockType is None: |  | ||||||
|             blockmetadb.update_block_info(blockHash, 'dataType', blockType) |  | ||||||
|         onionrevents.event('processblocks', data = {'block': myBlock, 'type': blockType, 'signer': signer, 'validSig': valid}) |         onionrevents.event('processblocks', data = {'block': myBlock, 'type': blockType, 'signer': signer, 'validSig': valid}) | ||||||
|     else: |  | ||||||
|         pass |  | ||||||
| 
 |  | ||||||
| def has_block(hash): |  | ||||||
|     ''' |  | ||||||
|         Check for new block in the list |  | ||||||
|     ''' |  | ||||||
|     conn = sqlite3.connect(dbfiles.block_meta_db) |  | ||||||
|     c = conn.cursor() |  | ||||||
|     if not stringvalidators.validate_hash(hash): |  | ||||||
|         raise Exception("Invalid hash") |  | ||||||
|     for result in c.execute("SELECT COUNT() FROM hashes WHERE hash = ?", (hash,)): |  | ||||||
|         if result[0] >= 1: |  | ||||||
|             conn.commit() |  | ||||||
|             conn.close() |  | ||||||
|             return True |  | ||||||
|         else: |  | ||||||
|             conn.commit() |  | ||||||
|             conn.close() |  | ||||||
|             return False |  | ||||||
|     return False |  | ||||||
|  | @ -68,3 +68,6 @@ def get_messages(peer): | ||||||
|         existing = list(existing) |         existing = list(existing) | ||||||
|         key_store.delete('r' + peer) |         key_store.delete('r' + peer) | ||||||
|     return Response(json.dumps(existing)) |     return Response(json.dumps(existing)) | ||||||
|  | 
 | ||||||
|  | #@flask_blueprint.route('/chatapi/connect/<peer>') | ||||||
|  | #def create_connection(peer) | ||||||
|  | @ -36,58 +36,3 @@ def exit_with_error(text=''): | ||||||
|     if text != '': |     if text != '': | ||||||
|         logger.error(text) |         logger.error(text) | ||||||
|     sys.exit(1) |     sys.exit(1) | ||||||
| 
 |  | ||||||
| class Chat: |  | ||||||
|     def __init__(self, pluginapi): |  | ||||||
|         self.peer = None |  | ||||||
|         self.transport = None |  | ||||||
|         self.shutdown = False |  | ||||||
|         self.pluginapi = pluginapi |  | ||||||
|      |  | ||||||
|     def _sender_loop(self): |  | ||||||
|         print('Enter a message to send, with ctrl-d or -s on a new line.') |  | ||||||
|         print('-c on a new line or ctrl-c stops') |  | ||||||
|         message = '' |  | ||||||
|         while not self.shutdown: |  | ||||||
|             try: |  | ||||||
|                 message += input() |  | ||||||
|                 if message == '-s': |  | ||||||
|                     raise EOFError |  | ||||||
|                 elif message == '-c': |  | ||||||
|                     raise KeyboardInterrupt |  | ||||||
|                 else: |  | ||||||
|                     message += '\n' |  | ||||||
|             except EOFError: |  | ||||||
|                 message = json.dumps({'m': message, 't': epoch.get_epoch()}) |  | ||||||
|                 print(basicrequests.do_post_request(self.pluginapi.onionr, 'http://%s/chat/sendto' % (self.transport,), port=self.socks, data=message)) |  | ||||||
|                 message = '' |  | ||||||
|             except KeyboardInterrupt: |  | ||||||
|                 self.shutdown = True |  | ||||||
| 
 |  | ||||||
|     def create(self): |  | ||||||
|         try: |  | ||||||
|             peer = sys.argv[2] |  | ||||||
|             if not stringvalidators.validate_pub_key(peer): |  | ||||||
|                 exit_with_error('Invalid public key specified') |  | ||||||
|         except IndexError: |  | ||||||
|             exit_with_error('You must specify a peer public key') |  | ||||||
|         self.peer = peer |  | ||||||
|         # Ask peer for transport address by creating block for them |  | ||||||
|         peer_transport_address = bootstrapservice.bootstrap_client_service(peer) |  | ||||||
|         self.transport = peer_transport_address |  | ||||||
|         self.socks = config.get('tor.socksport') |  | ||||||
| 
 |  | ||||||
|         print('connected with', peer, 'on', peer_transport_address) |  | ||||||
|         if basicrequests.do_get_request('http://%s/ping' % (peer_transport_address,), ignoreAPI=True, port=self.socks) == 'pong!': |  | ||||||
|             print('connected', peer_transport_address) |  | ||||||
|             threading.Thread(target=self._sender_loop).start() |  | ||||||
| 
 |  | ||||||
| def on_init(api, data = None): |  | ||||||
|     ''' |  | ||||||
|         This event is called after Onionr is initialized, but before the command |  | ||||||
|         inputted is executed. Could be called when daemon is starting or when |  | ||||||
|         just the client is running. |  | ||||||
|     ''' |  | ||||||
|     pluginapi = api |  | ||||||
|     chat = Chat(pluginapi) |  | ||||||
|     return |  | ||||||
|  |  | ||||||
|  | @ -60,9 +60,9 @@ def list_sentbox(): | ||||||
|     deleted = kv.get('deleted_mail') |     deleted = kv.get('deleted_mail') | ||||||
|     if deleted is None: |     if deleted is None: | ||||||
|         deleted = [] |         deleted = [] | ||||||
|     for x in list_copy: |     for sent in list_copy: | ||||||
|         if x['hash'] in deleted: |         if sent['hash'] in deleted: | ||||||
|             sentbox_list.remove(x) |             sentbox_list.remove(sent) | ||||||
|             continue |             continue | ||||||
|         x['name'] = contactmanager.ContactManager(x['peer'], saveUser=False).get_info('name') |         sent['name'] = contactmanager.ContactManager(sent['peer'], saveUser=False).get_info('name') | ||||||
|     return json.dumps(sentbox_list) |     return json.dumps(sentbox_list) | ||||||
|  |  | ||||||
							
								
								
									
										5
									
								
								onionr/static-data/default-plugins/searchengine/info.json
									
										
									
									
									
										Executable file
									
								
							
							
						
						
									
										5
									
								
								onionr/static-data/default-plugins/searchengine/info.json
									
										
									
									
									
										Executable file
									
								
							|  | @ -0,0 +1,5 @@ | ||||||
|  | { | ||||||
|  |     "name" : "searchengine", | ||||||
|  |     "version" : "0.0.0", | ||||||
|  |     "author" : "0gitnick" | ||||||
|  | } | ||||||
							
								
								
									
										24
									
								
								onionr/static-data/default-plugins/searchengine/main.py
									
										
									
									
									
										Executable file
									
								
							
							
						
						
									
										24
									
								
								onionr/static-data/default-plugins/searchengine/main.py
									
										
									
									
									
										Executable file
									
								
							|  | @ -0,0 +1,24 @@ | ||||||
|  | ''' | ||||||
|  |     Onionr - Private P2P Communication | ||||||
|  | 
 | ||||||
|  |     Search engine plugin for Onionr, to search for  | ||||||
|  | ''' | ||||||
|  | ''' | ||||||
|  |     This program is free software: you can redistribute it and/or modify | ||||||
|  |     it under the terms of the GNU General Public License as published by | ||||||
|  |     the Free Software Foundation, either version 3 of the License, or | ||||||
|  |     (at your option) any later version. | ||||||
|  | 
 | ||||||
|  |     This program is distributed in the hope that it will be useful, | ||||||
|  |     but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  |     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||||
|  |     GNU General Public License for more details. | ||||||
|  | 
 | ||||||
|  |     You should have received a copy of the GNU General Public License | ||||||
|  |     along with this program.  If not, see <https://www.gnu.org/licenses/>. | ||||||
|  | ''' | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | plugin_name = 'searchengine' | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | @ -14,6 +14,7 @@ | ||||||
|     <link rel="stylesheet" href="/chat/css/convos.css"> |     <link rel="stylesheet" href="/chat/css/convos.css"> | ||||||
|     <script defer src='/shared/navbar.js'></script> |     <script defer src='/shared/navbar.js'></script> | ||||||
|     <script defer src='/shared/misc.js'></script> |     <script defer src='/shared/misc.js'></script> | ||||||
|  |     <script defer src='/chat/messages/js'></script> | ||||||
|     <script defer src='/chat/js/message-feed.js'></script> |     <script defer src='/chat/js/message-feed.js'></script> | ||||||
|     <script defer src='/chat/js/main.js'></script> |     <script defer src='/chat/js/main.js'></script> | ||||||
| </head> | </head> | ||||||
|  |  | ||||||
|  | @ -17,5 +17,8 @@ | ||||||
|     along with this program.  If not, see <https://www.gnu.org/licenses/>
 |     along with this program.  If not, see <https://www.gnu.org/licenses/>
 | ||||||
| */ | */ | ||||||
| let MessageCache = class { | let MessageCache = class { | ||||||
|      |     constructor(user) { | ||||||
|  |         this.user = user | ||||||
|  |         this.cache = [] // array of Messages
 | ||||||
|  |     } | ||||||
| } | } | ||||||
							
								
								
									
										26
									
								
								onionr/static-data/www/chat/js/messages.js
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								onionr/static-data/www/chat/js/messages.js
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,26 @@ | ||||||
|  | /* | ||||||
|  |     Onionr - Private P2P Communication | ||||||
|  | 
 | ||||||
|  |     Onionr chat message objects | ||||||
|  | 
 | ||||||
|  |     This program is free software: you can redistribute it and/or modify | ||||||
|  |     it under the terms of the GNU General Public License as published by | ||||||
|  |     the Free Software Foundation, either version 3 of the License, or | ||||||
|  |     (at your option) any later version. | ||||||
|  | 
 | ||||||
|  |     This program is distributed in the hope that it will be useful, | ||||||
|  |     but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  |     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||||
|  |     GNU General Public License for more details. | ||||||
|  | 
 | ||||||
|  |     You should have received a copy of the GNU General Public License | ||||||
|  |     along with this program.  If not, see <https://www.gnu.org/licenses/>
 | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | let Message = class { | ||||||
|  |     constructor(text, to, time){ | ||||||
|  |         this.text = text // string
 | ||||||
|  |         this.to = to // bool. False = not outgoing
 | ||||||
|  |         this.time = time // epoch int
 | ||||||
|  |     } | ||||||
|  | } | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue