mirror of
https://github.com/Rolands-Laucis/Socio.git
synced 2026-05-15 14:15:57 -06:00
removed session id field
This commit is contained in:
parent
2be4413998
commit
3f425d5442
7 changed files with 15 additions and 24 deletions
|
|
@ -18,7 +18,7 @@ import { ParseQueryTables, ParseQueryVerb, SocioArgHas, SocioArgsParse } from '.
|
|||
export class SocioClient {
|
||||
// private:
|
||||
#ws = null
|
||||
#ses_id = null
|
||||
#client_id = null
|
||||
#is_ready = false
|
||||
#authenticated=false
|
||||
|
||||
|
|
@ -58,7 +58,7 @@ export class SocioClient {
|
|||
|
||||
switch (kind) {
|
||||
case 'CON':
|
||||
this.#ses_id = data;
|
||||
this.#client_id = data;
|
||||
this.#is_ready(true); //resolve promise to true
|
||||
if (this.verbose) done(`WebSocket connected.`, this.name);
|
||||
|
||||
|
|
@ -110,7 +110,7 @@ export class SocioClient {
|
|||
//private method - accepts infinite arguments of data to send and will append these params as new key:val pairs to the parent object
|
||||
#send(kind='', ...data){ //data is an array of parameters to this func, where every element (after first) is an object. First param can also not be an object in some cases
|
||||
if(data.length < 1) soft_error('Not enough arguments to send data! kind;data:', kind, ...data) //the first argument must always be the data to send. Other params may be objects with aditional keys to be added in the future
|
||||
this.#ws.send(JSON.stringify(Object.assign({}, { client_id: this.#ses_id, kind: kind, data:data[0] }, ...data.slice(1))))
|
||||
this.#ws.send(JSON.stringify(Object.assign({}, { client_id: this.#client_id, kind: kind, data:data[0] }, ...data.slice(1))))
|
||||
this.#HandleInfo('sent:', kind, data)
|
||||
}
|
||||
|
||||
|
|
@ -188,7 +188,7 @@ export class SocioClient {
|
|||
return false
|
||||
}
|
||||
|
||||
get client_id(){return this.#ses_id}
|
||||
get client_id(){return this.#client_id}
|
||||
ready() { return new Promise(res => this.#is_ready = res) }
|
||||
|
||||
#HandleError(e) {
|
||||
|
|
@ -208,19 +208,19 @@ export class SocioClient {
|
|||
|
||||
//check auth
|
||||
if (SocioArgHas('auth', { parsed: args }) && !this.#authenticated)
|
||||
throw (`Client ${this.#ses_id} tried to execute an auth query without being authenticated`, sql, this.name)
|
||||
throw (`Client ${this.#client_id} tried to execute an auth query without being authenticated`, sql, this.name)
|
||||
|
||||
//check perms
|
||||
if (SocioArgHas('perm', { parsed: args })) {
|
||||
const verb = ParseQueryVerb(sql)
|
||||
if (!verb)
|
||||
throw (`Client ${this.#ses_id} sent an unrecognized SQL query first clause. [#verb-issue]`, sql, this.name)
|
||||
throw (`Client ${this.#client_id} sent an unrecognized SQL query first clause. [#verb-issue]`, sql, this.name)
|
||||
const tables = ParseQueryTables(sql)
|
||||
if (!tables)
|
||||
throw (`Client ${this.#ses_id} sent an SQL query without table names. [#table-name-issue]`, sql, this.name)
|
||||
throw (`Client ${this.#client_id} sent an SQL query without table names. [#table-name-issue]`, sql, this.name)
|
||||
|
||||
if (!(verb in this.#perms) || !tables.every(t => this.#perms[verb].includes(t)))
|
||||
throw (`Client ${this.#ses_id} has insufficient permissions for query!`, verb, tables, this.name)
|
||||
throw (`Client ${this.#client_id} has insufficient permissions for query!`, verb, tables, this.name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@ export class SocioSession {
|
|||
#perms = {} //verb:[tables strings] keeps a dict of access permissions of verb type and to which tables this session has been granted
|
||||
|
||||
//public:
|
||||
ses_id = null //you are free to set this to whatever, so that you can later identify it by any means. Usually set it to whatever your session cookie is for this client on your web server
|
||||
verbose = true
|
||||
|
||||
constructor(client_id = '', browser_ws_conn = null, { verbose = true, default_perms = {} } = {}) {
|
||||
|
|
|
|||
12
core/core.js
12
core/core.js
|
|
@ -52,7 +52,7 @@ export class SocioServer{
|
|||
this.#sessions[client_id] = new SocioSession(client_id, conn, { verbose: this.verbose })
|
||||
|
||||
//pass the object to the connection hook, if it exists
|
||||
if (this.#lifecycle_hooks.con) //here you are free to set a session ID as SocioSession.ses_id. Like whatever your web server generates. Then use the ClientIDsOfSession(ses_id) to get the web socket clients using that backend web server session
|
||||
if (this.#lifecycle_hooks.con)
|
||||
this.#lifecycle_hooks.con(this.#sessions[client_id], req)
|
||||
|
||||
//notify the client of their ID
|
||||
|
|
@ -114,10 +114,7 @@ export class SocioServer{
|
|||
if (client_id in this.#sessions)
|
||||
this.#sessions[client_id].Send('UPD', {
|
||||
id: data.id,
|
||||
result: await this.Query({
|
||||
...data,
|
||||
ses_id: this.#sessions[client_id].ses_id
|
||||
})
|
||||
result: await this.Query(data)
|
||||
})
|
||||
|
||||
//set up hook
|
||||
|
|
@ -129,7 +126,7 @@ export class SocioServer{
|
|||
const is_select = QueryIsSelect(data.sql)
|
||||
if (client_id in this.#sessions) {
|
||||
//have to do the query in every case
|
||||
const res = this.Query({ ...data, ses_id: this.#sessions[client_id].ses_id })
|
||||
const res = this.Query(data)
|
||||
if (is_select) //wait for result, if a result is expected, and send it back
|
||||
this.#sessions[client_id].Send('SQL', { id: data.id, result: await res })
|
||||
}
|
||||
|
|
@ -241,9 +238,6 @@ export class SocioServer{
|
|||
GetClientSession(client_id=''){
|
||||
return this.#sessions[client_id] || null
|
||||
}
|
||||
ClientIDsOfSession(ses_id = ''){
|
||||
return this.#sessions?.filter(s => s.ses_id === ses_id)?.map(s => s.id) || []
|
||||
}
|
||||
|
||||
#HandleError(e) {
|
||||
if (this.hard_crash) throw e
|
||||
|
|
|
|||
|
|
@ -17,8 +17,7 @@ import { SocioServer } from 'socio/core.js'
|
|||
|
||||
//SocioServer needs a "query" function that it can call to fetch data. This would usually be your preffered ORM lib interface raw query function, but really this function is as simple as input and output, so it can do whatever you want. Like read from a txt file or whatever. It should be async and Socio will always await its response to send back to the client.
|
||||
//id is a unique auto incrementing index for the query itself that is sent from the client - not really important for you, but perhaps for debugging.
|
||||
//ses_id is the session identifier, for which one or more clients (with their own ID) may have connected, that you can use to validate the sql access params or whatever. You can also use it to ask Socio for the Session of this client, to do whatever you want with it.
|
||||
const QueryWrap = async ({ id = 0, ses_id = '', sql = '', params = {} } = {}) => (await sequelize.query(sql, { logging: false, raw: true, replacements: params }))[0]
|
||||
const QueryWrap = async ({ id = 0, sql = '', params = {} } = {}) => (await sequelize.query(sql, { logging: false, raw: true, replacements: params }))[0]
|
||||
|
||||
//The actual instance of the manager on port 3000 using the created query function. Verbose will make it print all incoming and outgoing traffic from all sockets in a pretty printed look :)
|
||||
const manager = new SocioServer({ port: 3000 }, QueryWrap, {verbose:true} )
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ await sequelize.query('INSERT INTO Users VALUES("John", 69);')
|
|||
//set up the WebSocket SocioServer and give it the DB querying function that comes from whatever your DB interface lib provides.
|
||||
//it needs the raw sql string, which can contain formatting parameters - insert dynamic data into the string.
|
||||
//Either you in a wrapper function or your DB interface lib should do the sql validation and sanitization, as this lib does not!
|
||||
async function QueryWrap({ id = 0, ses_id = '', sql = '', params = {} } = {}) {
|
||||
async function QueryWrap({ id = 0, sql = '', params = {} } = {}) {
|
||||
return (await sequelize.query(sql, { logging: false, raw: true, replacements: params }))[0]
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ await sequelize.query('INSERT INTO Users VALUES("John", 69);')
|
|||
//set up the WebSocket SocioServer and give it the DB querying function that comes from whatever your DB interface lib provides.
|
||||
//it needs the raw sql string, which can contain formatting parameters - insert dynamic data into the string.
|
||||
//Either you in a wrapper function or your DB interface lib should do the sql validation and sanitization, as this lib does not!
|
||||
async function QueryWrap({ id = 0, ses_id = '', sql = '', params = {} } = {}){
|
||||
async function QueryWrap({ id = 0, sql = '', params = {} } = {}){
|
||||
return (await sequelize.query(sql, { logging: false, raw: true, replacements: params }))[0]
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -18,13 +18,12 @@
|
|||
<Code>
|
||||
{`const ws = new SocioClient('ws://localhost:3000', {verbose:true, name:'Main'})
|
||||
await ws.ready()
|
||||
clienID = ws.ses_id
|
||||
|
||||
ws.subscribe({ sql: "SELECT COUNT(*) AS RESULT FROM users WHERE name = :name;--socio", params: { name: 'Bob' } }, (res) => {
|
||||
bob_count = res[0].RESULT
|
||||
})
|
||||
|
||||
ws.subscribe({ sql: "SELECT * FROM users;--socio"}, (res) => {})`}
|
||||
ws.query({ sql: "INSERT INTO users VALUES(:name);--socio-auth-perm"}, {name:'Joe'})`}
|
||||
</Code>
|
||||
</Border>
|
||||
</section>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue