! Due to user-id's being randomly generated it is now much more likely that id's can't be parsed by javascript properly
Json-bigint should help alleviate this issue by correctly parsing numbers for us - Removing url method in favor of new url property in server config model + Building UserConfigs and ServerConfig from typical JS Obects This should reduce some up front complexity regarding parameters ! Fix: using new url property instead of protocol + host + port - Reducing upfront complexity of public channels API * Also moving to using new updated server.url property * Channels also handles its part of updating the dom now bigint parsing in configs now * More switches to server.url property
This commit is contained in:
parent
89bd257213
commit
72f3461341
13
freechat-client/package-lock.json
generated
13
freechat-client/package-lock.json
generated
@ -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",
|
||||
|
@ -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",
|
||||
|
@ -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 = $('<input>').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)
|
||||
}
|
||||
|
@ -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<Channel>, messages: Array<Message>) {
|
||||
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) {
|
||||
|
@ -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(
|
||||
$('<li>').append(
|
||||
$('<p>').append(
|
||||
$('<button>').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<Channel>}
|
||||
*/
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
@ -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]
|
||||
|
@ -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: {
|
||||
|
@ -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('=|:^)')
|
||||
|
@ -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']
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user