Skip to content
This repository has been archived by the owner on Nov 13, 2024. It is now read-only.

Commit

Permalink
support token refresh, allow raw data access, don't use the ws packag…
Browse files Browse the repository at this point in the history
…e (requires node 22+)
  • Loading branch information
williamhorning committed Jul 11, 2024
1 parent f0e4344 commit a9022d9
Show file tree
Hide file tree
Showing 6 changed files with 87 additions and 55 deletions.
10 changes: 9 additions & 1 deletion src/api/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,17 @@ export class client {

const ws = await socket.connect({ ...opts, api_token: rest.api_token });

const token = await new Promise((resolve) => {
ws.on('auth', (data) => {
resolve(data.token);
});
}) as string;

rest.api_token = token;

const u = new uploads({
base_url: opts.uploads_url,
token: rest.api_token,
token,
});

return new client(rest, ws, u);
Expand Down
4 changes: 2 additions & 2 deletions src/api/rest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,7 @@ export class rest_api {
throw new Error('failed to login', { cause: data });
}

return new rest_api({ ...data, api_url });
return new rest_api({ api_url, token: data.token, account: data.account });
}

/** signup for an account on meower */
Expand Down Expand Up @@ -333,6 +333,6 @@ export class rest_api {
throw new Error('failed to signup', { cause: data });
}

return new rest_api({ ...data, api_url });
return new rest_api({ api_url, token: data.token, account: data.account });
}
}
119 changes: 70 additions & 49 deletions src/api/socket.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import { EventEmitter } from 'jsr:@denosaurs/[email protected]';
import { type api_post, post } from '../interfaces/post.ts';
import { EventEmitter } from "jsr:@denosaurs/[email protected]";
import { type api_post, post } from "../interfaces/post.ts";
import type { api_user } from "../interfaces/user.ts";

/** options used to connect to the meower socket */
export interface socket_connect_opts {
/** the api url */
api_url: string;
/** the api token */
api_token: string;
/** the password */
password?: string;
/** the socket url */
socket_url: string;
/** the username */
Expand Down Expand Up @@ -35,6 +38,14 @@ export interface socket_packet {
listener?: string;
}

/** auth information from the socket */
export interface socket_auth_event {
/** api user */
account: api_user;
/** api token */
token: string;
}

/** access to the meower socket */
export class socket extends EventEmitter<{
socket_open: [];
Expand All @@ -46,6 +57,7 @@ export class socket extends EventEmitter<{
create_message: [post];
edit_message: [post];
delete_message: [{ id: string }];
auth: [socket_auth_event];
}> {
private socket: WebSocket;
private opts: socket_connect_opts;
Expand All @@ -58,63 +70,62 @@ export class socket extends EventEmitter<{
}

private setup() {
this.socket.onopen = () => {
this.emit('socket_open');

this.send({
'cmd': 'direct',
'val': {
'cmd': 'type',
'val': 'js',
},
});

this.send({
'cmd': 'authpswd',
'val': {
'username': this.opts.username,
'pswd': this.opts.api_token,
},
});

setInterval(() => {
if (this.socket.readyState === 1) {
this.send({
'cmd': 'ping',
'val': '',
});
}
}, 30000);
};
this.emit("socket_open");

this.send({
'cmd': 'direct',
'val': {
'cmd': 'type',
'val': 'js',
},
});

this.socket.onclose = () => this.emit('socket_close');
this.send({
"cmd": "authpswd",
"val": {
"username": this.opts.username,
"pswd": this.opts.password ?? this.opts.api_token,
},
});

setInterval(() => {
if (this.socket.readyState === 1) {
this.send({
"cmd": "ping",
"val": "",
});
}
}, 30000);

this.socket.onclose = () => this.emit("socket_close");

this.socket.onmessage = (event) => {
const packet = JSON.parse(event.data);

if (!packet) return;

this.emit('packet', packet);
this.emit("packet", packet);
this.emit(`cmd-${packet.cmd}`, packet);

if (packet.listener) {
this.emit(`listener-${packet.listener}`, packet);
}
};

this.socket.onerror = (err) => this.emit('socket_error', err);
this.socket.onerror = (err) => this.emit("socket_error", err);

this.on('cmd-direct', (packet) => {
this.on("cmd-direct", (packet) => {
if (
!packet.val || typeof packet.val !== 'object' ||
!packet.val || typeof packet.val !== "object" ||
Array.isArray(packet.val)
) return;

if (packet.val.p) {
const event = 'payload' in packet.val
? 'edit_message'
: 'create_message';
const api = (packet.val.payload ?? packet.val) as unknown as api_post;
const event = "payload" in packet.val
? "edit_message"
: "create_message";
const api =
(packet.val.payload ?? packet.val) as unknown as api_post;
const p = new post({
api_token: this.opts.api_token,
api_url: this.opts.api_url,
Expand All @@ -124,17 +135,28 @@ export class socket extends EventEmitter<{
this.emit(event, p);
}

if (packet.val.mode === 'delete_post') {
this.emit('delete_message', { id: packet.val.id as string });
if (packet.val.mode === "delete_post") {
this.emit("delete_message", { id: packet.val.id as string });
}
});

this.on("cmd-direct", (packet) => {
const val = packet.val as Record<string, unknown>;

if (val.mode !== "auth") return;

const auth_event = val.payload as socket_auth_event;

this.opts.api_token = auth_event.token;

this.emit("auth", auth_event)
})
}

static async connect(opts: socket_connect_opts): Promise<socket> {
const ws =
new (globalThis.WebSocket ? WebSocket : ((await import('ws')).default))(
opts.socket_url,
);
const ws = new WebSocket(
opts.socket_url,
);
await new Promise((resolve) => ws.onopen = resolve);
return new socket(ws, opts);
}
Expand All @@ -147,10 +169,9 @@ export class socket extends EventEmitter<{
/** reconnect to the socket */
async reconnect() {
this.disconnect();
const socket =
new (globalThis.WebSocket ? WebSocket : ((await import('ws')).default))(
this.opts.socket_url,
);
const socket = new WebSocket(
this.opts.socket_url,
);
await new Promise((resolve) => socket.onopen = resolve);
this.socket = socket;
this.setup();
Expand Down
3 changes: 2 additions & 1 deletion src/interfaces/chat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,8 @@ export class chat {
private api_url: string;
private api_token: string;
private api_username: string;
private raw: api_chat;
/** raw api data */
raw: api_chat;
/** chat id */
id!: string;
/** whether pinning is allowed */
Expand Down
3 changes: 2 additions & 1 deletion src/interfaces/post.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,8 @@ export class post {
private api_url: string;
private api_token: string;
private api_username: string;
private raw: api_post;
/** raw api data */
raw: api_post;
/** attachments */
attachments?: api_attachment[];
/** post id */
Expand Down
3 changes: 2 additions & 1 deletion src/interfaces/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,8 @@ export class user {
private api_url: string;
private api_token: string;
private api_username: string;
private raw: api_user;
/** raw user data */
raw: api_user;
/** user id */
id!: string;
/** user avatar file id */
Expand Down

0 comments on commit a9022d9

Please sign in to comment.