diff --git a/freechat-client/package-lock.json b/freechat-client/package-lock.json index 9402301..aa0d497 100644 --- a/freechat-client/package-lock.json +++ b/freechat-client/package-lock.json @@ -225,6 +225,11 @@ "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" }, + "bignumber.js": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.1.tgz", + "integrity": "sha512-IdZR9mh6ahOBv/hYGiXyVuyCetmGJhtYkqLBpTStdhEGjegpPlUawydyaF3pbIOFynJTpllEs+NP+CS9jKFLjA==" + }, "boolean": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/boolean/-/boolean-3.0.3.tgz", @@ -656,6 +661,14 @@ "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.6.0.tgz", "integrity": "sha512-JVzAR/AjBvVt2BmYhxRCSYysDsPcssdmTFnzyLEts9qNwmjmu4JTAMYubEfwVOSwpQ1I1sKKFcxhZCI2buerfw==" }, + "json-bigint": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz", + "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==", + "requires": { + "bignumber.js": "^9.0.0" + } + }, "json-buffer": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", diff --git a/freechat-client/package.json b/freechat-client/package.json index 5e758a1..bbe1458 100644 --- a/freechat-client/package.json +++ b/freechat-client/package.json @@ -12,6 +12,7 @@ "bootstrap": "^4.6.0", "got": "^11.8.2", "jquery": "^3.6.0", + "json-bigint": "^1.0.0", "jsonwebtoken": "^8.5.1", "popper.js": "^1.16.1", "typescript": "^4.2.3", diff --git a/freechat-client/src/auth.js b/freechat-client/src/auth.js index 065a6d5..14759d6 100644 --- a/freechat-client/src/auth.js +++ b/freechat-client/src/auth.js @@ -1,36 +1,36 @@ const { ipcRenderer } = require('electron') const got = require('got') const channels = require('./channels.js') +const URL = require('url') function push_srv(remote, user, enabled) { let classes = 'btn btn-outline-secondary btn-nav-settings' if(!enabled) { classes += ' disabled' } + let url = URL.parse(remote['url']) let btn = $('').attr({ type: 'button', 'class': classes, - id: remote['hostname'], + id: url.host, value: remote['name'] }) $('#server-list').append(btn) - let cb = async () => { await channels.list(remote, user) } - $(`#${remote['hostname']}`).on('click', cb) + let cb = async () => { await channels.server_button_cb(remote, user) } + document.getElementById(url.host).onclick = cb } /** - * @param {String} protocol http|https - * @param {String} host Just the hostname one.two.xyz - * @param {u16} port Port to use + * @param {String} url http(s) url of target * @param {String} user.secret * @param {Number} user.id * * @returns {String|null} JWT */ -async function login(protocol, host, port, user) { - const url = `${protocol}://${host}:${port}/login` - const response = await got(url, { +async function login(baseurl, user) { + const url = `${baseurl}/login` + const response = await got.post(url, { searchParams: { id: user['id'], secret: user['secret'] }, responseType: 'json', // If DNS is seriously taking this long we honestly should just give up @@ -55,13 +55,14 @@ exports.init = async function() { const user = config.data['servers'][index]['user'] try { - const jwt = await login(remote['protocol'], remote['hostname'], remote['port'], user) + console.log('remote params: ', remote) + const jwt = await login(remote['url'], user) config.data['servers'][index]['user']['jwt'] = jwt user['jwt'] = jwt - push_srv(remote, user, true); + push_srv(remote, user, enabled=true); } catch (err) { - push_srv(remote, user, false) + push_srv(remote, user, enabled=false) const e_container = { error: err, server: remote, creds: user } console.log('Failure to communicate with server: ', e_container) } diff --git a/freechat-client/src/cache.ts b/freechat-client/src/cache.ts index 882d41c..7409cb1 100644 --- a/freechat-client/src/cache.ts +++ b/freechat-client/src/cache.ts @@ -20,16 +20,6 @@ class ServerCache { } } - url(): String{ - let url = `${this.config.protocol}://${this.config.hostname}` - // Only add the port WITH THE COLON if the config requires it - if(this.config.port) { - url += `:${this.config.port}` - } - - return url - } - push_message(message: Message) { let ref = this.messages.get(message.cid) if(ref) { @@ -50,7 +40,7 @@ export class Cache { add_server(hostname: String, servercfg: ServerConfig, channels: Array, messages: Array) { let new_entry = new ServerCache(servercfg, channels, messages) - this.servers.set(servercfg.hostname, new_entry) + this.servers.set(servercfg.url, new_entry) } add_message(hostname: String, message: Message) { diff --git a/freechat-client/src/channels.js b/freechat-client/src/channels.js index 386701b..cdc1f8e 100644 --- a/freechat-client/src/channels.js +++ b/freechat-client/src/channels.js @@ -1,6 +1,8 @@ // Requesting channel data here +const { Channel } = require('./types') const $ = require('jquery') const got = require('got') +const URL = require('url') const msg = require('./messages.js') @@ -9,6 +11,10 @@ const ANY_CHANNEL = 0 const VOICE_KIND = 1 const TEXT_KIND = 2 +exports.ANY_CHANNEL = ANY_CHANNEL +exports.VOICE_KIND = VOICE_KIND +exports.TEXT_KIND = TEXT_KIND + /** * Channel button id's have the format of ${hostname}:${channel['name']} @@ -27,18 +33,20 @@ const TEXT_KIND = 2 * @param {i32} channel.kind */ function push(server, user, channel) { + let remote = URL.parse(server.url) + let chan_id = `${remote.hostname}:${channel['name']}` $('#channels-list').append( $('').append( $('').append( $('').attr({ 'class': 'btn btn-outline-secondary btn-nav-settings channel-btn', - id: `${server.hostname}:${channel['name']}`, + id: chan_id, }).text(channel['name']) ) ) ) // Not using jquery for this because it breaks with weird id names really easily - let ref = document.getElementById(`${server.hostname}:${channel['name']}`) + let ref = document.getElementById(chan_id) ref.addEventListener('click', () => { // now for the actual handler where we deal with clicks $('#channel-name').text('#' + channel['name']) @@ -58,34 +66,59 @@ function push(server, user, channel) { * Listener callback for actually getting a list of channels * @param {Object} server Object containing server configuration * @param {Object} user Object containing user access data + * @param {Number} kind * */ -exports.list = async function(server, user) { +async function list(server, user, kind) { - // TODO: add some kind of caching system here: should probably check for some kind of cache here but hey fuck it right? + // TODO: caching bro $('#channels-list').html('') $('#server-name').text(server['name']) try { - const url = `${server['protocol']}://${server['hostname']}:${server['port']}/channels/list` - const text_channel_response = await got(url, { - searchParams: { id: user['id'], jwt: user['jwt'], kind: TEXT_KIND }, + const url = `${server['url']}/channels/list` + const response = await got(url, { + searchParams: { id: user['id'], jwt: user['jwt'], kind: kind }, responseType: 'json' }) - let text_channels = text_channel_response.body['channels'] - console.log('text: ', text_channels) + let channels_json = response.body['channels'] - - const channels = text_channels - - - for(const channel of channels) { - console.log(channel) - push(server, user, channel) + let channels_parsed = [] + for(const chan of channels_json) { + console.log("channel: ", chan) + let c = new Channel(chan['name'], chan['kind'], chan['id'], chan['desc']) + channels_parsed.push(c) } + return channels_parsed } catch (err) { console.log(err) console.log(err['name']) + return [] + } +} + +/** + * @param {List} + */ +async function assemble_channels_dom(channels) { + for(const channel of channels) { + console.log(channel) + push(server, user, channel) + } +} + +/** + * @param {String} remote.url + * @param {String} user.id + * @param {String} user.jwt + */ +exports.server_button_cb = async function(remote, user) { + let vc = await list(remote, user, VOICE_KIND) + let tc = await list(remote, user, TEXT_KIND) + vc.push(...tc) + + for(const chan of vc) { + push(remote, user, chan) } } diff --git a/freechat-client/src/config.js b/freechat-client/src/config.js index b337995..5dcb645 100644 --- a/freechat-client/src/config.js +++ b/freechat-client/src/config.js @@ -2,6 +2,10 @@ const { ArgumentParser } = require('argparse') const fs = require('fs').promises const syncFs = require('fs') +// required because freechat by default uses i64/u64 in json payloads +// timestamps will get especially rekt'd if we don't parse things correctly +const JSONBig = require('json-bigint') + class Config { /** * @@ -38,7 +42,7 @@ exports.from_cli_parser = function(parser) { // Allow errors from here to bubble up instead of handling them fs.readFile(path).then(file => { - const json = JSON.parse(file) + const json = JSONBig.parse(file) for(const key of Object.keys(json)) { ret.data[key] = json[key] diff --git a/freechat-client/src/messages.js b/freechat-client/src/messages.js index ca298b4..709f4cd 100644 --- a/freechat-client/src/messages.js +++ b/freechat-client/src/messages.js @@ -34,9 +34,7 @@ function rebind_message_box(server, auth, channel_id) { * @param {String} auth.jwt | jwt for quick auth * @param {u64} auth.id user | id required by most/all endpoints * - * @param {String} server.hostname | Hostname of target server - * @param {u16} server.port | Port to use for server - * @param {String} server.protocol | http/https (no colon) + * @param {String} server.url | Url of target server * * @param {u64} channel_id | Channel id to query * @param {i64} start_time | Unix time to start fetching messages from @@ -47,7 +45,7 @@ function rebind_message_box(server, auth, channel_id) { * @throws HTTPResponseError */ async function get_range(auth, server, channel_id, start_time, end_time, limit) { - const url = `${server.protocol}://${server.hostname}:${server.port}/message/get_range` + const url = `${server.url}/message/get_range` const response = await got(url, { searchParams: { diff --git a/freechat-client/src/settings.js b/freechat-client/src/settings.js index 1be94c3..adac901 100644 --- a/freechat-client/src/settings.js +++ b/freechat-client/src/settings.js @@ -17,9 +17,7 @@ exports.add_server_to_config = async function() { try { await auth.login( - data['server']['protocol'], - data['server']['host'], - data['server']['port'], + data['server']['url'], data['user'] ) $('#admni-json-err').text('=|:^)') diff --git a/freechat-client/src/types.ts b/freechat-client/src/types.ts index 0b4cdc8..ba6e346 100644 --- a/freechat-client/src/types.ts +++ b/freechat-client/src/types.ts @@ -48,15 +48,27 @@ export class Channel { } export class ServerConfig { - hostname: String - port: Number - protocol: String + url: String + name: String + description: String - constructor(protocol: String, hostname: String, port: Number) { - this.protocol = protocol - this.hostname = hostname - this.port = port + constructor(json: Object) { + this.url = json['url'] + this.name = json['name'] + this.description = json['description'] } } +export class UserConfig { + id: Number + jwt: String|null + permissions: Number + secret: String + constructor(json: Object) { + this.id = json['id'] + this.jwt = json['jwt'] + this.permissions = json['permissions'] + this.secret = json['secret'] + } +}
').append( $('').attr({ 'class': 'btn btn-outline-secondary btn-nav-settings channel-btn', - id: `${server.hostname}:${channel['name']}`, + id: chan_id, }).text(channel['name']) ) ) ) // Not using jquery for this because it breaks with weird id names really easily - let ref = document.getElementById(`${server.hostname}:${channel['name']}`) + let ref = document.getElementById(chan_id) ref.addEventListener('click', () => { // now for the actual handler where we deal with clicks $('#channel-name').text('#' + channel['name']) @@ -58,34 +66,59 @@ function push(server, user, channel) { * Listener callback for actually getting a list of channels * @param {Object} server Object containing server configuration * @param {Object} user Object containing user access data + * @param {Number} kind * */ -exports.list = async function(server, user) { +async function list(server, user, kind) { - // TODO: add some kind of caching system here: should probably check for some kind of cache here but hey fuck it right? + // TODO: caching bro $('#channels-list').html('') $('#server-name').text(server['name']) try { - const url = `${server['protocol']}://${server['hostname']}:${server['port']}/channels/list` - const text_channel_response = await got(url, { - searchParams: { id: user['id'], jwt: user['jwt'], kind: TEXT_KIND }, + const url = `${server['url']}/channels/list` + const response = await got(url, { + searchParams: { id: user['id'], jwt: user['jwt'], kind: kind }, responseType: 'json' }) - let text_channels = text_channel_response.body['channels'] - console.log('text: ', text_channels) + let channels_json = response.body['channels'] - - const channels = text_channels - - - for(const channel of channels) { - console.log(channel) - push(server, user, channel) + let channels_parsed = [] + for(const chan of channels_json) { + console.log("channel: ", chan) + let c = new Channel(chan['name'], chan['kind'], chan['id'], chan['desc']) + channels_parsed.push(c) } + return channels_parsed } catch (err) { console.log(err) console.log(err['name']) + return [] + } +} + +/** + * @param {List} + */ +async function assemble_channels_dom(channels) { + for(const channel of channels) { + console.log(channel) + push(server, user, channel) + } +} + +/** + * @param {String} remote.url + * @param {String} user.id + * @param {String} user.jwt + */ +exports.server_button_cb = async function(remote, user) { + let vc = await list(remote, user, VOICE_KIND) + let tc = await list(remote, user, TEXT_KIND) + vc.push(...tc) + + for(const chan of vc) { + push(remote, user, chan) } } diff --git a/freechat-client/src/config.js b/freechat-client/src/config.js index b337995..5dcb645 100644 --- a/freechat-client/src/config.js +++ b/freechat-client/src/config.js @@ -2,6 +2,10 @@ const { ArgumentParser } = require('argparse') const fs = require('fs').promises const syncFs = require('fs') +// required because freechat by default uses i64/u64 in json payloads +// timestamps will get especially rekt'd if we don't parse things correctly +const JSONBig = require('json-bigint') + class Config { /** * @@ -38,7 +42,7 @@ exports.from_cli_parser = function(parser) { // Allow errors from here to bubble up instead of handling them fs.readFile(path).then(file => { - const json = JSON.parse(file) + const json = JSONBig.parse(file) for(const key of Object.keys(json)) { ret.data[key] = json[key] diff --git a/freechat-client/src/messages.js b/freechat-client/src/messages.js index ca298b4..709f4cd 100644 --- a/freechat-client/src/messages.js +++ b/freechat-client/src/messages.js @@ -34,9 +34,7 @@ function rebind_message_box(server, auth, channel_id) { * @param {String} auth.jwt | jwt for quick auth * @param {u64} auth.id user | id required by most/all endpoints * - * @param {String} server.hostname | Hostname of target server - * @param {u16} server.port | Port to use for server - * @param {String} server.protocol | http/https (no colon) + * @param {String} server.url | Url of target server * * @param {u64} channel_id | Channel id to query * @param {i64} start_time | Unix time to start fetching messages from @@ -47,7 +45,7 @@ function rebind_message_box(server, auth, channel_id) { * @throws HTTPResponseError */ async function get_range(auth, server, channel_id, start_time, end_time, limit) { - const url = `${server.protocol}://${server.hostname}:${server.port}/message/get_range` + const url = `${server.url}/message/get_range` const response = await got(url, { searchParams: { diff --git a/freechat-client/src/settings.js b/freechat-client/src/settings.js index 1be94c3..adac901 100644 --- a/freechat-client/src/settings.js +++ b/freechat-client/src/settings.js @@ -17,9 +17,7 @@ exports.add_server_to_config = async function() { try { await auth.login( - data['server']['protocol'], - data['server']['host'], - data['server']['port'], + data['server']['url'], data['user'] ) $('#admni-json-err').text('=|:^)') diff --git a/freechat-client/src/types.ts b/freechat-client/src/types.ts index 0b4cdc8..ba6e346 100644 --- a/freechat-client/src/types.ts +++ b/freechat-client/src/types.ts @@ -48,15 +48,27 @@ export class Channel { } export class ServerConfig { - hostname: String - port: Number - protocol: String + url: String + name: String + description: String - constructor(protocol: String, hostname: String, port: Number) { - this.protocol = protocol - this.hostname = hostname - this.port = port + constructor(json: Object) { + this.url = json['url'] + this.name = json['name'] + this.description = json['description'] } } +export class UserConfig { + id: Number + jwt: String|null + permissions: Number + secret: String + constructor(json: Object) { + this.id = json['id'] + this.jwt = json['jwt'] + this.permissions = json['permissions'] + this.secret = json['secret'] + } +}