From 5c2f8a6cf8cc7256043aeb0ddff5cc117d7cc9c5 Mon Sep 17 00:00:00 2001 From: Romaric Mourgues Date: Thu, 20 Apr 2023 15:06:43 +0200 Subject: [PATCH] Remove 10 more --- .../src/app/components/inputs/input-enter.jsx | 46 --- .../src/app/components/inputs/input-icon.jsx | 47 ---- .../src/app/components/inputs/switch.tsx | 84 ------ .../src/app/components/picker/picker.jsx | 262 ----------------- .../src/app/components/picker/picker.scss | 55 ---- .../src/app/components/table/table.scss | 98 ------- .../src/app/components/table/table.tsx | 243 ---------------- .../Collections/MultipleSecuredConnections.js | 98 ------- .../Collections/SecuredConnection.js | 265 ------------------ .../src/app/deprecated/websocket/websocket.js | 184 ------------ 10 files changed, 1382 deletions(-) delete mode 100755 tdrive/frontend/src/app/components/inputs/input-enter.jsx delete mode 100755 tdrive/frontend/src/app/components/inputs/input-icon.jsx delete mode 100755 tdrive/frontend/src/app/components/inputs/switch.tsx delete mode 100755 tdrive/frontend/src/app/components/picker/picker.jsx delete mode 100755 tdrive/frontend/src/app/components/picker/picker.scss delete mode 100755 tdrive/frontend/src/app/components/table/table.scss delete mode 100755 tdrive/frontend/src/app/components/table/table.tsx delete mode 100755 tdrive/frontend/src/app/deprecated/CollectionsV1/Collections/MultipleSecuredConnections.js delete mode 100755 tdrive/frontend/src/app/deprecated/CollectionsV1/Collections/SecuredConnection.js delete mode 100755 tdrive/frontend/src/app/deprecated/websocket/websocket.js diff --git a/tdrive/frontend/src/app/components/inputs/input-enter.jsx b/tdrive/frontend/src/app/components/inputs/input-enter.jsx deleted file mode 100755 index 2f8dec22..00000000 --- a/tdrive/frontend/src/app/components/inputs/input-enter.jsx +++ /dev/null @@ -1,46 +0,0 @@ -/* eslint-disable react/prop-types */ -import React, { Component } from 'react'; - -import Input from './input.jsx'; -import Icon from '@components/icon/icon.jsx'; -import './inputs.scss'; - -export default class InputEnter extends Component { - constructor() { - super(); - } - render() { - var parentClassName = ''; - - if (this.props.big) { - parentClassName += ' big '; - } - if (this.props.medium) { - parentClassName += ' medium '; - } - if (this.props.small) { - parentClassName += ' small '; - } - - if ( - parentClassName.indexOf('medium') === parentClassName.indexOf('small') && - parentClassName.indexOf('big') === parentClassName.indexOf('small') && - parentClassName.indexOf('big') < 0 - ) { - parentClassName += ' medium'; - } - - return ( -
- - -
- ); - } -} diff --git a/tdrive/frontend/src/app/components/inputs/input-icon.jsx b/tdrive/frontend/src/app/components/inputs/input-icon.jsx deleted file mode 100755 index e31672df..00000000 --- a/tdrive/frontend/src/app/components/inputs/input-icon.jsx +++ /dev/null @@ -1,47 +0,0 @@ -/* eslint-disable react/prop-types */ -import React, { Component } from 'react'; - -import Input from './input.jsx'; -import Icon from '@components/icon/icon.jsx'; -import './inputs.scss'; - -export default class InputIcon extends Component { - constructor() { - super(); - } - render() { - var parentClassName = ''; - - if (this.props.big) { - parentClassName += ' big '; - } - if (this.props.medium) { - parentClassName += ' medium '; - } - if (this.props.small) { - parentClassName += ' small '; - } - - if ( - parentClassName.indexOf('medium') === parentClassName.indexOf('small') && - parentClassName.indexOf('big') === parentClassName.indexOf('small') && - parentClassName.indexOf('big') < 0 - ) { - parentClassName += ' medium'; - } - - return ( -
- - -
- ); - } -} diff --git a/tdrive/frontend/src/app/components/inputs/switch.tsx b/tdrive/frontend/src/app/components/inputs/switch.tsx deleted file mode 100755 index d2bca800..00000000 --- a/tdrive/frontend/src/app/components/inputs/switch.tsx +++ /dev/null @@ -1,84 +0,0 @@ -import React from 'react'; -import { Switch } from 'antd'; - -import './inputs.scss'; - -export default (props: { - big?: boolean; - medium?: boolean; - small?: boolean; - loading?: boolean; - className?: string; - label?: string; - checked?: boolean; - disabled?: boolean; - onChange: (value: boolean) => void; -}) => { - const renderSwitch = () => { - let className = props.className || ''; - - if (props.big) { - className += ' big '; - } - if (props.medium) { - className += ' medium '; - } - if (props.small) { - className += ' small '; - } - - if ( - className.indexOf('medium') === className.indexOf('small') && - className.indexOf('big') === className.indexOf('small') && - className.indexOf('big') < 0 - ) { - className += ' medium'; - } - return ( - { - props.onChange(value); - }} - className={className} - loading={props.loading} - disabled={props.disabled} - /> - ); - }; - - let parentClassName = ''; - - if (props.big) { - parentClassName += ' big '; - } - if (props.medium) { - parentClassName += ' medium '; - } - if (props.small) { - parentClassName += ' small '; - } - - if ( - parentClassName.indexOf('medium') === parentClassName.indexOf('small') && - parentClassName.indexOf('big') === parentClassName.indexOf('small') && - parentClassName.indexOf('big') < 0 - ) { - parentClassName += ' medium'; - } - - if (props.label) { - return ( -
- {renderSwitch()} -
{props.label}
-
- ); - } else { - return renderSwitch(); - } -}; diff --git a/tdrive/frontend/src/app/components/picker/picker.jsx b/tdrive/frontend/src/app/components/picker/picker.jsx deleted file mode 100755 index a59175d9..00000000 --- a/tdrive/frontend/src/app/components/picker/picker.jsx +++ /dev/null @@ -1,262 +0,0 @@ -/* eslint-disable react/jsx-key */ -import React, { Component } from 'react'; -import AutoComplete from 'components/auto-complete/auto-complete'; -import Icon from '@components/icon/icon.jsx'; -import Languages from '@features/global/services/languages-service'; -import './picker.scss'; - -export default class Picker extends React.Component { - /* - placeholder : string, - search : Array of search function, - renderItem(item) : how to render item - renderItemChoosen(item) : how to add item in input - renderItemSimply(item) : what user will type on input and what we have to replace - onChangeSuggested(list) - onChange(list) : - canCreate - onCreate - disableNavigationKey : - */ - constructor(props) { - super(props); - this.state = { - currentSelected: props.value || [], - inputValue: '', - currentList: [], - selected: [], - }; - this.alreadyBackspace = false; - } - componentWillUnmount() { - document.removeEventListener('click', this.outsideClickListener); - } - componentDidMount() { - if (!this.props.inline) { - this.focus(); - } - - var element = this.container; - this.outsideClickListener = event => { - if (!element.contains(event.target) && document.contains(event.target)) { - this.setState({ focused: false }); - } - }; - this.outsideClickListener = this.outsideClickListener.bind(this); - document.addEventListener('click', this.outsideClickListener); - } - UNSAFE_componentWillUpdate(nextProps, nextState) { - if (nextProps.value != this.props.value) { - nextState.currentSelected = nextProps.value; - } - return true; - } - onSelect(item) { - this.alreadyBackspace = true; - if (item && (item.id === undefined || item.id < 0) && item.front_id === undefined) { - this.onCreate(item.textSearched); - return; - } - var newList = this.state.currentSelected; - for (var i = 0; i < newList.length; i++) { - if (newList[i].id == item.id) { - this.setState({ inputValue: '' }); - return false; - } - } - newList.push(item); - this.setState({ currentSelected: newList }); - this.setState({ inputValue: '' }); - if (this.props.onChange) { - this.props.onChange(newList); - } - this.focus(); - } - onRemove(item) { - var newList = this.state.currentSelected; - var index = newList.indexOf(item); - if (index >= 0) { - newList.splice(index, 1); - this.setState({ currentSelected: newList }); - if (this.props.onChange) { - this.props.onChange(newList); - } - } - this.focus(); - } - onBackspace() { - if (this.alreadyBackspace) { - // if already typed on backspace once - var newList = this.state.currentSelected; - newList.splice(newList.length - 1, 1); - this.setState({ currentSelected: newList }); - } else { - this.alreadyBackspace = true; - } - } - onCreate(text) { - if (this.props.onCreate) { - var item = this.props.onCreate(text, item => { - this.onSelect(item); - }); - } - } - focus() { - if (this.autocomplete_node) { - this.autocomplete_node.focus(); - } - } - render() { - var that = this; - var objects = [ -
-
- {this.state.currentSelected.map(item => { - return this.props.renderItemChoosen(item); - })} - {!this.props.readOnly && ( - { - text = this.state.inputValue; - this.props.search(text, list => { - if (that.props.canCreate && text.length > 0) { - list.push({ id: -1, autocomplete_id: list.length, textSearched: text }); - } - cb(list); - }); - }, - ]} - renderItemChoosen={[ - item => { - if (item.id < 0 && this.props.canCreate) { - return item.textSearched; - } else { - return this.props.renderItemSimply(item); - } - }, - ]} - max={[this.props.max || 10]} - renderItem={[() => {}]} - regexHooked={[/(.*)/]} - placeholder={ - this.state.currentSelected.length - ? '' - : this.props.placeholder || - Languages.t('scenes.apps.drive.left.search', [], 'Search') - } - onChange={evt => { - this.alreadyBackspace = false; - this.setState({ inputValue: evt.target.value }); - }} - onSelect={item => { - this.onSelect(item); - }} - value={this.state.inputValue} - onChangeCurrentList={(list, selected) => { - this.setState({ currentList: list, selected: selected }); - if (this.props.onChangeSuggested) { - this.props.onChangeSuggested(list); - } - }} - hideResult={true} - onBackspace={() => { - this.onBackspace(); - }} - disableNavigationKey={this.props.disableNavigationKey} - showResultsOnInit={true} - onHide={() => this.setState({ focused: false })} - ref={node => { - this.autocomplete_node = node; - }} - /> - )} -
-
, - ]; - - if (!this.props.readOnly) { - if (!this.props.inline) { - objects.push(
{!!this.props.title && this.props.title}
); - } - - var results = []; - - if (this.state.currentList.length > 0) { - results = this.state.currentList.map((item, index) => { - if (item.id < 0) { - return ( -
{ - evt.stopPropagation(); - evt.preventDefault(); - this.onSelect(item); - }} - > -
- - Create {this.props.renderItem(item.textSearched)} -
-
- ); - } else { - return ( -
{ - evt.stopPropagation(); - evt.preventDefault(); - this.onSelect(item); - }} - > -
{this.props.renderItem(item)}
-
- ); - } - }); - } - if (this.props.inline) { - results = ( -
- {results} -
- ); - } - objects = objects.concat(results); - } - - objects = ( -
{ - this.focus(); - this.setState({ focused: true }); - }} - ref={node => (this.container = node)} - className={ - 'picker_container ' + - (this.props.readOnly ? 'readOnly ' : '') + - (this.props.inline ? 'inline ' : '') + - (this.state.focused ? 'focused ' : '') + - this.props.className - } - > - {objects} -
- ); - - return objects; - } -} diff --git a/tdrive/frontend/src/app/components/picker/picker.scss b/tdrive/frontend/src/app/components/picker/picker.scss deleted file mode 100755 index 48bd9b66..00000000 --- a/tdrive/frontend/src/app/components/picker/picker.scss +++ /dev/null @@ -1,55 +0,0 @@ -.picker_container { - position: relative; - border-radius: var(--border-radius-large); - &.inline { - transition: box-shadow 0.2s; - - .dropmenu { - opacity: 0; - transition: opacity 0.2s; - pointer-events: none; - } - - &.focused { - &.readOnly { - box-shadow: none !important; - } - - .autocomplete { - box-shadow: none !important; - } - .dropmenu { - opacity: 1; - pointer-events: all; - } - } - } -} - -.picker { - .pickerInput { - border-radius: var(--border-radius-base); - display: flex; - flex-wrap: wrap; - position: relative; - background: #f2f2f2; - - &.readOnly { - margin: 0; - display: inline; - padding: 0; - background: transparent; - } - - .autocomplete { - flex: 1; - min-width: 50px; - position: unset; - input { - background: inherit; - margin-top: 0px; - margin-bottom: 0px; - } - } - } -} diff --git a/tdrive/frontend/src/app/components/table/table.scss b/tdrive/frontend/src/app/components/table/table.scss deleted file mode 100755 index 7feb9aaf..00000000 --- a/tdrive/frontend/src/app/components/table/table.scss +++ /dev/null @@ -1,98 +0,0 @@ -rm .table { - overflow: hidden; - border-radius: var(--border-radius-base); - margin-bottom: 16px; - border: 1px solid var(--grey-background); - font-weight: 500; - - &.unfocused { - box-shadow: none; - } - - &.loading { - opacity: 0.5; - - .tr .item .line { - pointer-events: none; - border-radius: var(--border-radius-large); - height: 16px; - margin-top: 8px; - width: 200px; - animation-duration: 1s; - animation-fill-mode: forwards; - animation-iteration-count: infinite; - animation-name: placeHolderShimmer; - animation-timing-function: linear; - background-repeat: repeat !important; - background-image: linear-gradient( - to right, - var(--grey-light) 0px, - #f2f2f2 120px, - var(--grey-light) 234px - ) !important; - - & > * { - opacity: 0 !important; - } - } - } - - .headerTable { - background: var(--grey-background); - font-weight: 700; - font-size: 14px; - display: flex; - padding: 8px; - border-bottom: 1px solid var(--grey-background); - } - - .footerTable { - text-align: center; - line-height: 32px; - font-size: 14px; - padding: 5px 10px; - border-top: 1px solid var(--grey-background); - border-bottom: 1px solid var(--grey-background); - } - .contentTable { - .tr { - display: flex; - border-bottom: 1px solid var(--grey-background); - padding: 8px; - font-size: 12px; - - &:hover { - background: var(--grey-background); - } - - &:last-child { - border-bottom: none; - } - - & > div { - position: relative; - min-height: 32px; - - & > .absolute_position { - width: 100%; - position: absolute; - height: 100%; - display: flex; - } - } - } - - .fix_text_padding_medium { - padding: 8px 0; - display: inline-block; - line-height: 18px; - } - - .text-complete-width { - overflow: hidden; - flex: 1; - white-space: nowrap; - text-overflow: ellipsis; - } - } -} diff --git a/tdrive/frontend/src/app/components/table/table.tsx b/tdrive/frontend/src/app/components/table/table.tsx deleted file mode 100755 index 8180e99c..00000000 --- a/tdrive/frontend/src/app/components/table/table.tsx +++ /dev/null @@ -1,243 +0,0 @@ -/* eslint-disable @typescript-eslint/no-explicit-any */ -/* eslint-disable jsx-a11y/anchor-is-valid */ -import React, { Component } from 'react'; -import Languages from '@features/global/services/languages-service'; -import Button from 'components/buttons/button.jsx'; -import InputIcon from 'components/inputs/input-icon.jsx'; -import './table.scss'; - -type Props = { - column?: any; - noHeader: boolean; - onAdd: () => void; - onRequestMore: (refresh: boolean) => Promise; - onSearch: (query: string, maxResults: number, callback: (res: any[]) => void) => Promise; - updatedData: (data: any) => any; - addText?: string; - resultsPerPage?: number; - unFocused: boolean; -}; -type State = { - data: null | any[]; - searchResults: any[]; - loading: boolean; - has_more: boolean; - page: number; - searching: boolean; -}; - -export default class Table extends Component { - searchFieldValue = ''; - searchRunning = false; - searchRunningTimeout: number | null = null; - - constructor(props: Props) { - super(props); - this.state = { - data: null, - searchResults: [], - loading: true, - has_more: true, - page: 0, - searching: false, - }; - Languages.addListener(this); - } - - componentWillUnmount() { - Languages.removeListener(this); - } - - componentDidMount() { - if (this.state.data === null) { - this.requestMore(true); - } - } - - search() { - if (this.searchFieldValue?.length <= 2) { - return false; - } - if (this.searchRunning) { - clearTimeout(this.searchRunningTimeout as number); - this.searchRunningTimeout = window.setTimeout(() => { - this.search(); - }, 1000); - return; - } - - this.setState({ - loading: true, - }); - - this.searchRunning = true; - this.props.onSearch(this.searchFieldValue, 10, (data: any[]) => { - this.searchRunning = false; - this.setState({ - loading: false, - searchResults: data, - }); - }); - } - - renderItem(col: any, item: any) { - if (col.render) { - return col.render(item); - } else { - return
{col.dataIndex ? item[col.dataIndex] : ''}
; - } - } - - requestMore(refresh = false) { - this.setState({ loading: true }); - this.props.onRequestMore(refresh).then(res => { - const hasMore = res.length !== (this.state.data || []).length; - this.setState({ loading: false, data: res, has_more: hasMore }); - }); - } - - setPosition() { - if (!!this.props.onSearch && !this.props.onAdd) return 'flex-end'; - else return 'space-between'; - } - - nextPage() { - this.setState({ page: this.state.page + 1 }); - if (this.getPageData().length < (this.state.page + 1) * this.getResultsPerPage()) { - this.requestMore(); - } - } - - getPageData() { - const from = this.state.page * this.getResultsPerPage(); - return (this.state.data || []).slice(0, from + this.getResultsPerPage()); - } - - getResultsPerPage(): number { - return this.props.resultsPerPage || 50; - } - - render() { - let page_data = this.state.searching ? this.state.searchResults : this.getPageData(); - page_data = page_data - .map(data => { - data = this.props.updatedData ? this.props.updatedData(data) : data; - if (!data) { - return false; - } - return data; - }) - .filter(i => i); - - return ( -
-
- {this.props.onAdd && ( -
- -
- {!this.props.noHeader && ( -
- {this.props.column.map((col: any, i: number) => { - return ( -
- {col.title} -
- ); - })} -
- )} -
- {(page_data || []).length === 0 && !this.state.loading && ( -
-
- {Languages.t('components.user_picker.modal_no_result')} -
-
- )} - {(page_data || []).length === 0 && - !!this.state.loading && - Array(this.state.searching ? 1 : this.getResultsPerPage()).map((_, i: number) => { - return ( -
-
-
-
-
- ); - })} - {(page_data || []).map((data: any, i: number) => { - return ( -
- {this.props.column.map((col: any, j: number) => { - return ( -
- {this.renderItem(col, data)} -
- ); - })} -
- ); - })} -
- {!this.state.searching && - !!this.state.has_more && - page_data.length >= this.getResultsPerPage() && ( - - )} -
-
- ); - } -} diff --git a/tdrive/frontend/src/app/deprecated/CollectionsV1/Collections/MultipleSecuredConnections.js b/tdrive/frontend/src/app/deprecated/CollectionsV1/Collections/MultipleSecuredConnections.js deleted file mode 100755 index 2e8d7334..00000000 --- a/tdrive/frontend/src/app/deprecated/CollectionsV1/Collections/MultipleSecuredConnections.js +++ /dev/null @@ -1,98 +0,0 @@ -import SecuredConnection from './SecuredConnection.js'; -/** MultipleSecuredConnections - * Manage multiple secured connections as one (multiple publish and centralized event manager) - */ - -export default class MultipleSecuredConnections { - constructor(callback, options) { - if (!options) { - options = {}; - } - - //Options : - this.disableDuplicates = options.disableDuplicates !== false; - - this.secured_connections = {}; - this.callback = callback; - - this.removing_secured_connections_timeouts = {}; - } - - publish(data) { - Object.keys(this.secured_connections).forEach(secured_connection_key => { - var secured_connection = this.secured_connections[secured_connection_key]; - secured_connection.publish(data, () => {}); - }); - } - - event(route, event, data) { - //Disable duplicates - var string = JSON.stringify(data); - if ( - string === this.last_event && - this.disableDuplicates && - !(event === 'close' || event === 'open' || event === 'init') - ) { - return; - } - this.last_event = string; - - if (!data) { - data = {}; - } - data._route = route; - if (this.callback) this.callback(event, data); - } - - addConnection(route, option, http_options, key) { - if (this.secured_connections[route]) { - this.secured_connections[route].removing = false; - if (this.removing_secured_connections_timeouts[route]) { - clearTimeout(this.removing_secured_connections_timeouts[route]); - } - return; - } - - if (this.secured_connections[route]) { - return; - } - - this.secured_connections[route] = new SecuredConnection( - route, - option, - (event, data) => { - this.event(route, event, data); - }, - http_options, - key, - ); - } - - removeConnection(route) { - if (!this.secured_connections[route] || this.secured_connections[route].removing) { - return; - } - - if (this.removing_secured_connections_timeouts[route]) { - clearTimeout(this.removing_secured_connections_timeouts[route]); - } - - this.secured_connections[route].removing = true; - this.removing_secured_connections_timeouts[route] = setTimeout(() => { - if (this.secured_connections[route]) { - this.secured_connections[route].close(); - delete this.secured_connections[route]; - } - }, 10000); - } - - getRoutes() { - return Object.keys(this.secured_connections); - } - - closeAll() { - Object.keys(this.secured_connections).foEach(route => { - this.removeConnection(route); - }); - } -} diff --git a/tdrive/frontend/src/app/deprecated/CollectionsV1/Collections/SecuredConnection.js b/tdrive/frontend/src/app/deprecated/CollectionsV1/Collections/SecuredConnection.js deleted file mode 100755 index a3fd7553..00000000 --- a/tdrive/frontend/src/app/deprecated/CollectionsV1/Collections/SecuredConnection.js +++ /dev/null @@ -1,265 +0,0 @@ -import Api from '@features/global/framework/api-service'; -import ws from '@deprecated/websocket/websocket.js'; -import CryptoJS from 'crypto-js'; -import sha256 from 'crypto-js/sha256'; -/** SecuredConnection - * Create websockets encrypted connection - */ -import Globals from '@features/global/services/globals-tdrive-app-service'; - -export default class SecuredConnection { - constructor(route, options, callback, http_options, collectionId) { - this.ready = false; - this.collectionId = collectionId; - - this.route = route; - this.options = options; - - this.callback = callback; - - //Room idea - this.websocket_id = ''; - - //Store keys - this.keys = []; - this.keys_by_version = {}; - this.publish_buffer = []; - this.http_options = http_options; - - this.init(http_options); - - Globals.window.CryptoAES = CryptoJS.AES; - } - - init(http_options) { - this.ready = false; - - this.options.get_options = http_options; - - var data = { - collection_id: this.route, - options: this.options, - _grouped: true, - }; - Api.GroupedQueryApiPost('/ajax/core/collections/init', data, res => { - var did_get = false; - - if (res.data) { - var data = res.data; - this.ready = true; - this.websocket_id = data.room_id; - this.receiveNewKey(data.key, data.key_version, false); - this.open(); - - if (data.get) { - this.callback('get', { collectionId: this.collectionId, data: data.get }); - did_get = true; - } - } - - if (!did_get) { - this.callback('init', {}); - } - }); - } - - open() { - var websocket_id = this.websocket_id; - ws.subscribe( - 'collections/' + websocket_id, - (uri, obj) => { - this.receiveEvent(obj); - }, - websocket_id, - ); - ws.onReconnect(websocket_id, () => { - this.close(); - this.init(); - }); - - this.callback('open', {}); - this.publish(); - } - - close() { - var websocket_id = this.websocket_id; - ws.offReconnect(websocket_id); - ws.unsubscribe( - 'collections/' + websocket_id, - (uri, obj) => { - this.receiveEvent(obj); - }, - websocket_id, - ); - - this.callback('close', {}); - } - - publish(data, callback) { - if (!data) { - //Read buffer - - var publish_buffer = JSON.parse(JSON.stringify(this.publish_buffer)); - this.publish_buffer = []; - - publish_buffer.forEach(item => { - this.publish(item, callback); - }); - - return; - } - - if (!this.ready) { - this.publish_buffer.push(data); - return; - } - - var websocket_id = this.websocket_id; - var encrypted = this.encrypt(data); - ws.publish('collections/' + websocket_id, encrypted); - - if (callback) { - callback(); - } - } - - receiveEvent(event) { - if (event.encrypted) { - event = this.decrypt(event); - } - - if (event.new_key) { - this.receiveNewKey(event.new_key, event.key_version, true); - return; - } - - if (!event) { - return; - } - - this.callback('event', event); - } - - //Receive new key as addon for previous key or as replacing key (sent by php server) - receiveNewKey(key, version, asAddon) { - if (asAddon) { - var lastKey = this.keys[this.keys.length - 1]; - key = sha256(lastKey.key + key).toString(); //Mix keys - } - - this.keys.push({ - key: key, - version: version, - }); - this.keys_by_version[version] = key; - - this.prepareEncryptKey(); - } - - prepareEncryptKey() { - var lastKey = this.keys[this.keys.length - 1]; - - try { - if (this.prepared_key_original !== lastKey) { - this.prepared_key_salt = CryptoJS.lib.WordArray.random(256); - this.prepared_key_original = lastKey; - this.prepared_key = CryptoJS.PBKDF2(lastKey.key, this.prepared_key_salt, { - hasher: CryptoJS.algo.SHA512, - keySize: 64 / 8, - iterations: 9, - }); - } - } catch (e) { - console.log(e); - } - - return this.prepared_key; - } - - encrypt(data) { - var lastKey = this.keys[this.keys.length - 1]; - var prepared_key = this.prepareEncryptKey(); - if (!prepared_key) { - prepared_key = ''; - } - var iv = CryptoJS.lib.WordArray.random(16); - - var encrypted = CryptoJS.AES.encrypt(JSON.stringify(data), prepared_key, { iv: iv }); - - // eslint-disable-next-line no-redeclare - var data = { - encrypted: CryptoJS.enc.Base64.stringify(encrypted.ciphertext), - iv: CryptoJS.enc.Hex.stringify(iv), - salt: CryptoJS.enc.Hex.stringify(this.prepared_key_salt), - key_version: lastKey.version, - }; - - return data; - } - - decrypt(data) { - if (!data.key_version) { - return false; - } - let res = ''; - let str = ''; - try { - if (data.public) { - return typeof data.public === 'string' ? JSON.parse(data.public) : data.public; - } - - var encrypted_data = data.encrypted; - - var key = this.keys_by_version[data.key_version]; - - if (!key) { - if ( - this.getKeyTimestamp(key) > this.getKeyTimestamp(this.keys[this.keys.length - 1].version) - ) { - //We have a old key, we have to update and request the message again - this.init(this.http_options); - //TODO reask lost message after init - } else { - //We have only newer keys, ask everybody to update - //TODO ws.publish('collections/' + websocket_id, encrypted); - } - return false; - } - - var salt = CryptoJS.enc.Hex.parse(data.salt); - var prepared_key = CryptoJS.PBKDF2(key, salt, { - hasher: CryptoJS.algo.SHA512, - keySize: 64 / 8, - iterations: 9, - }); - - var iv = CryptoJS.enc.Hex.parse(data.iv); - var bytes = CryptoJS.AES.decrypt(encrypted_data, prepared_key, { iv: iv }); - str = bytes.toString(CryptoJS.enc.Utf8); - - if (str) { - res = JSON.parse(str); - } else { - res = ''; - } - } catch (err) { - console.error('Unable to read encrypted websocket event', str, err.message); - } - - return res; - } - - getKeyTimestamp(key) { - try { - if (typeof key !== 'string') { - if (key !== undefined) { - console.log('wrong websocket key format: ', key); - } - return 0; - } - return parseInt((key || '').split('-')[1]); - } catch (e) { - console.log(key, e); - } - } -} diff --git a/tdrive/frontend/src/app/deprecated/websocket/websocket.js b/tdrive/frontend/src/app/deprecated/websocket/websocket.js deleted file mode 100755 index 036c2d1f..00000000 --- a/tdrive/frontend/src/app/deprecated/websocket/websocket.js +++ /dev/null @@ -1,184 +0,0 @@ -import Number from '@features/global/utils/Numbers'; -import Observable from '@deprecated/CollectionsV1/observable.js'; -import LoginService from '@features/auth/login-service'; -import Logger from '@features/global/framework/logger-service'; -import Globals from '@features/global/services/globals-tdrive-app-service'; -import WebSocket from '../../features/global/types/websocket-types'; - -/** - * @deprecated Keeps old PHP websocket working doing the bridge with the new implementation - */ -class DeprecatedWebsocket extends Observable { - constructor() { - super(); - this.logger = Logger.getLogger('Websocket'); - this.setObservableName('websockets'); - - this.ws = null; - this.connection = null; - this.afterError = false; - this.lastData = 1; - this.testNetwork = false; - - this.connected = true; - this.subscribed = {}; - this.subscribedKey = {}; - this.disconnectListeners = {}; - - this.alive_connected = true; - - this.firstTime = true; - this.last_reconnect_call = new Date(); - this.last_reconnect_call_if_needed = new Date(); - - window.websocketsManager = this; - - this.window_focus = true; - this.window_last_blur = new Date(); - this.deconnectionBlurTimeout = setTimeout(() => {}, 0); - Globals.window.addEventListener('focus', () => { - this.reconnectIfNeeded(60); - clearTimeout(this.deconnectionBlurTimeout); - this.didFocusedLastMinute = true; - this.window_focus = true; - this.window_last_blur = new Date(); - if (this.ws == null || new Date().getTime() - this.window_last_blur.getTime() > 30000) { - this.alive_connected = false; - this.alive(); - } - }); - Globals.window.addEventListener('blur', () => { - this.window_focus = false; - this.window_last_blur = new Date(); - }); - - this.alive.bind(this); - this.message.bind(this); - this.updateConnected.bind(this); - } - - //Send I'm alive ! - alive() { - var nw = new Date().getTime(); - if (!this.lastAlive || nw - this.lastAlive > 60000) { - // Wait at least 60 seconds - this.lastAlive = nw; - this.alive_timeout = setTimeout(() => { - this.alive_connected = false; - }, 5100); - this.reconnectIfNeeded(); - clearTimeout(this.alive_timeout); - this.alive_connected = true; - this.didFocusedLastMinute = Globals.isReactNative || Globals.window.document.hasFocus(); - } - } - - //Receive server message - message(unid, route, data) { - route = (route || '').split('previous::').pop(); - if (unid !== this.subscribedKey[route]) { - return; - } - if (this.subscribed[route]) { - this.subscribed[route].forEach(c => { - try { - c.callback(route, data); - } catch (err) { - console.log(err); - } - }); - } else { - this.unsubscribe(route); - } - } - - //Subscribe to channel - subscribe(route, callback, key) { - this.logger.debug(`Subscribe to ${route}`); - route = (route || '').split('previous::').pop(); - if (!key) { - key = callback.name; - } - if (!this.subscribed[route]) { - this.subscribed[route] = []; - } - this.subscribed[route].push({ name: key, callback: callback }); - if (this.subscribed[route].length === 1) { - const unid = Number.unid(); - this.subscribedKey[route] = unid; - WebSocket.get().join('previous::' + route, '', '', (type, data) => { - if (type === 'realtime:event') { - this.message(unid, data.name, data.data); - } - if (type === 'connected') { - this.updateConnected(true); - } - if (type === 'disconnected') { - this.updateConnected(false); - } - }); - } - } - - //Unsubscribe from channel - unsubscribe(route, callback, key) { - this.logger.debug(`Unsubscribe from ${route}`); - route = (route || '').split('previous::').pop(); - if (!key && callback) { - key = callback.name; - } - if (!key) { - key = 'default'; - } - if (!this.subscribed[route]) { - this.subscribed[route] = []; - } - var remaining = []; - this.subscribed[route].forEach(c => { - if (c.name !== key) { - remaining.push(c); - } - }); - this.subscribed[route] = remaining; - if (this.subscribed[route].length === 0) { - WebSocket.get().leave('previous::' + route, ''); - } - } - - publish(route, value) { - this.logger.debug(`Publish to ${route}`); - WebSocket.get().send('previous::' + route, value); - } - - reconnectIfNeeded(seconds = 30) { - if (new Date().getTime() - this.last_reconnect_call_if_needed.getTime() > seconds * 1000) { - //30 seconds - if (LoginService.currentUserId) { - LoginService.updateUser(); - } - - this.last_reconnect_call_if_needed = new Date(); - } - } - - onReconnect(id, callback) { - this.disconnectListeners[id] = callback; - } - - offReconnect(id) { - delete this.disconnectListeners[id]; - } - - updateConnected(state) { - if (state !== this.connected) { - this.connected = state; - this.notify(); - } - } - - isConnected() { - return this.connected; - } -} - -export default new DeprecatedWebsocket();