mirror of
https://github.com/spacebarchat/server.git
synced 2026-10-23 10:53:01 +00:00
Merge branch 'master' of https://github.com/fosscord/fosscord-server
This commit is contained in:
commit
b603b81629
216 files changed
+10585
-11466
No files matched your search
@@ -12,24 +12,30 @@ export class DmChannelDTO {
|
||||
type: number;
|
||||
|
||||
static async from(channel: Channel, excluded_recipients: string[] = [], origin_channel_id?: string) {
|
||||
const obj = new DmChannelDTO()
|
||||
obj.icon = channel.icon || null
|
||||
obj.id = channel.id
|
||||
obj.last_message_id = channel.last_message_id || null
|
||||
obj.name = channel.name || null
|
||||
obj.origin_channel_id = origin_channel_id || null
|
||||
obj.owner_id = channel.owner_id
|
||||
obj.type = channel.type
|
||||
obj.recipients = (await Promise.all(channel.recipients!.filter(r => !excluded_recipients.includes(r.user_id)).map(async r => {
|
||||
return await User.findOneOrFail({ where: { id: r.user_id }, select: PublicUserProjection })
|
||||
}))).map(u => new MinimalPublicUserDTO(u))
|
||||
return obj
|
||||
const obj = new DmChannelDTO();
|
||||
obj.icon = channel.icon || null;
|
||||
obj.id = channel.id;
|
||||
obj.last_message_id = channel.last_message_id || null;
|
||||
obj.name = channel.name || null;
|
||||
obj.origin_channel_id = origin_channel_id || null;
|
||||
obj.owner_id = channel.owner_id;
|
||||
obj.type = channel.type;
|
||||
obj.recipients = (
|
||||
await Promise.all(
|
||||
channel
|
||||
.recipients!.filter((r) => !excluded_recipients.includes(r.user_id))
|
||||
.map(async (r) => {
|
||||
return await User.findOneOrFail({ where: { id: r.user_id }, select: PublicUserProjection });
|
||||
})
|
||||
)
|
||||
).map((u) => new MinimalPublicUserDTO(u));
|
||||
return obj;
|
||||
}
|
||||
|
||||
excludedRecipients(excluded_recipients: string[]): DmChannelDTO {
|
||||
return {
|
||||
...this,
|
||||
recipients: this.recipients.filter(r => !excluded_recipients.includes(r.id))
|
||||
}
|
||||
recipients: this.recipients.filter((r) => !excluded_recipients.includes(r.id)),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,10 +8,10 @@ export class MinimalPublicUserDTO {
|
||||
username: string;
|
||||
|
||||
constructor(user: User) {
|
||||
this.avatar = user.avatar
|
||||
this.discriminator = user.discriminator
|
||||
this.id = user.id
|
||||
this.public_flags = user.public_flags
|
||||
this.username = user.username
|
||||
this.avatar = user.avatar;
|
||||
this.discriminator = user.discriminator;
|
||||
this.id = user.id;
|
||||
this.public_flags = user.public_flags;
|
||||
this.username = user.username;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,2 +1,2 @@
|
||||
export * from "./DmChannelDTO";
|
||||
export * from "./UserDTO";
|
||||
export * from "./UserDTO";
|
||||
@@ -71,7 +71,7 @@ export class Invite extends BaseClassWithoutId {
|
||||
@Column({ nullable: true })
|
||||
target_user_type?: number;
|
||||
|
||||
@Column({ nullable: true})
|
||||
@Column({ nullable: true })
|
||||
vanity_url?: boolean;
|
||||
|
||||
static async joinGuild(user_id: string, code: string) {
|
||||
|
||||
@@ -9,6 +9,7 @@ import {
|
||||
CreateDateColumn,
|
||||
Entity,
|
||||
FindConditions,
|
||||
Index,
|
||||
JoinColumn,
|
||||
JoinTable,
|
||||
ManyToMany,
|
||||
@@ -45,9 +46,11 @@ export enum MessageType {
|
||||
}
|
||||
|
||||
@Entity("messages")
|
||||
@Index(["channel_id", "id"], { unique: true })
|
||||
export class Message extends BaseClass {
|
||||
@Column({ nullable: true })
|
||||
@RelationId((message: Message) => message.channel)
|
||||
@Index()
|
||||
channel_id: string;
|
||||
|
||||
@JoinColumn({ name: "channel_id" })
|
||||
@@ -68,10 +71,13 @@ export class Message extends BaseClass {
|
||||
|
||||
@Column({ nullable: true })
|
||||
@RelationId((message: Message) => message.author)
|
||||
@Index()
|
||||
author_id: string;
|
||||
|
||||
@JoinColumn({ name: "author_id", referencedColumnName: "id" })
|
||||
@ManyToOne(() => User)
|
||||
@ManyToOne(() => User, {
|
||||
onDelete: "CASCADE",
|
||||
})
|
||||
author?: User;
|
||||
|
||||
@Column({ nullable: true })
|
||||
|
||||
@@ -10,7 +10,7 @@ export class Migration extends BaseClassWithoutId {
|
||||
@PrimaryIdAutoGenerated()
|
||||
id: number;
|
||||
|
||||
@Column({ type: 'bigint' })
|
||||
@Column({ type: "bigint" })
|
||||
timestamp: number;
|
||||
|
||||
@Column()
|
||||
|
||||
@@ -9,7 +9,8 @@ export class ApiError extends Error {
|
||||
}
|
||||
|
||||
withDefaultParams(): ApiError {
|
||||
if (this.defaultParams) return new ApiError(applyParamsToString(this.message, this.defaultParams), this.code, this.httpStatus);
|
||||
if (this.defaultParams)
|
||||
return new ApiError(applyParamsToString(this.message, this.defaultParams), this.code, this.httpStatus);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
export function containsAll(arr: any[], target: any[]) {
|
||||
return target.every(v => arr.includes(v));
|
||||
}
|
||||
return target.every((v) => arr.includes(v));
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
import "missing-native-js-functions";
|
||||
import fetch from "node-fetch";
|
||||
import ProxyAgent from 'proxy-agent';
|
||||
import readline from "readline";
|
||||
import fs from "fs/promises";
|
||||
import path from "path";
|
||||
@@ -52,7 +53,8 @@ async function download(url: string, dir: string) {
|
||||
try {
|
||||
// TODO: use file stream instead of buffer (to prevent crash because of high memory usage for big files)
|
||||
// TODO check file hash
|
||||
const response = await fetch(url);
|
||||
const agent = new ProxyAgent();
|
||||
const response = await fetch(url, { agent });
|
||||
const buffer = await response.buffer();
|
||||
const tempDir = await fs.mkdtemp("fosscord");
|
||||
fs.writeFile(path.join(tempDir, "Fosscord.zip"), buffer);
|
||||
@@ -72,7 +74,8 @@ async function getCurrentVersion(dir: string) {
|
||||
|
||||
async function getLatestVersion(url: string) {
|
||||
try {
|
||||
const response = await fetch(url);
|
||||
const agent = new ProxyAgent();
|
||||
const response = await fetch(url, { agent });
|
||||
const content = await response.json();
|
||||
return content.version;
|
||||
} catch (error) {
|
||||
|
||||
+15
-1
@@ -1,5 +1,10 @@
|
||||
import "missing-native-js-functions";
|
||||
import { ConfigValue, ConfigEntity, DefaultConfigOptions } from "../entities/Config";
|
||||
import path from "path";
|
||||
import fs from "fs";
|
||||
|
||||
// TODO: yaml instead of json
|
||||
// const overridePath = path.join(process.cwd(), "config.json");
|
||||
|
||||
var config: ConfigValue;
|
||||
var pairs: ConfigEntity[];
|
||||
@@ -12,8 +17,16 @@ export const Config = {
|
||||
if (config) return config;
|
||||
pairs = await ConfigEntity.find();
|
||||
config = pairsToConfig(pairs);
|
||||
config = (config || {}).merge(DefaultConfigOptions);
|
||||
|
||||
return this.set((config || {}).merge(DefaultConfigOptions));
|
||||
// try {
|
||||
// const overrideConfig = JSON.parse(fs.readFileSync(overridePath, { encoding: "utf8" }));
|
||||
// config = overrideConfig.merge(config);
|
||||
// } catch (error) {
|
||||
// fs.writeFileSync(overridePath, JSON.stringify(config, null, 4));
|
||||
// }
|
||||
|
||||
return this.set(config);
|
||||
},
|
||||
get: function get() {
|
||||
return config;
|
||||
@@ -38,6 +51,7 @@ function applyConfig(val: ConfigValue) {
|
||||
pair.value = obj;
|
||||
return pair.save();
|
||||
}
|
||||
// fs.writeFileSync(overridePath, JSON.stringify(val, null, 4));
|
||||
|
||||
return apply(val);
|
||||
}
|
||||
|
||||
+27
-3
@@ -15,6 +15,8 @@ export async function emitEvent(payload: Omit<Event, "created_at">) {
|
||||
// assertQueue isn't needed, because a queue will automatically created if it doesn't exist
|
||||
const successful = RabbitMQ.channel?.publish(id, "", Buffer.from(`${data}`), { type: payload.event });
|
||||
if (!successful) throw new Error("failed to send event");
|
||||
} else if (process.env.EVENT_TRANSMISSION === "process") {
|
||||
process.send?.({ type: "event", event: payload, id } as ProcessEvent);
|
||||
} else {
|
||||
events.emit(id, payload);
|
||||
}
|
||||
@@ -25,6 +27,7 @@ export async function initEvent() {
|
||||
if (RabbitMQ.connection) {
|
||||
} else {
|
||||
// use event emitter
|
||||
// use process messages
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,17 +42,38 @@ export interface ListenEventOpts {
|
||||
acknowledge?: boolean;
|
||||
}
|
||||
|
||||
export interface ProcessEvent {
|
||||
type: "event";
|
||||
event: Event;
|
||||
id: string;
|
||||
}
|
||||
|
||||
export async function listenEvent(event: string, callback: (event: EventOpts) => any, opts?: ListenEventOpts) {
|
||||
if (RabbitMQ.connection) {
|
||||
// @ts-ignore
|
||||
return rabbitListen(opts?.channel || RabbitMQ.channel, event, callback, { acknowledge: opts?.acknowledge });
|
||||
} else {
|
||||
} else if (process.env.EVENT_TRANSMISSION === "process") {
|
||||
const cancel = () => {
|
||||
events.removeListener(event, callback);
|
||||
process.removeListener("message", listener);
|
||||
process.setMaxListeners(process.getMaxListeners() - 1);
|
||||
};
|
||||
|
||||
const listener = (msg: ProcessEvent) => {
|
||||
msg.type === "event" && msg.id === event && callback({ ...msg.event, cancel });
|
||||
};
|
||||
|
||||
process.addListener("message", listener);
|
||||
process.setMaxListeners(process.getMaxListeners() + 1);
|
||||
|
||||
return cancel;
|
||||
} else {
|
||||
const listener = (opts: any) => callback({ ...opts, cancel });
|
||||
const cancel = () => {
|
||||
events.removeListener(event, listener);
|
||||
events.setMaxListeners(events.getMaxListeners() - 1);
|
||||
};
|
||||
events.setMaxListeners(events.getMaxListeners() + 1);
|
||||
events.addListener(event, (opts) => callback({ ...opts, cancel }));
|
||||
events.addListener(event, listener);
|
||||
|
||||
return cancel;
|
||||
}
|
||||
|
||||
@@ -8,9 +8,9 @@ export function FieldErrors(fields: Record<string, { code?: string; message: str
|
||||
_errors: [
|
||||
{
|
||||
message,
|
||||
code: code || "BASE_TYPE_INVALID"
|
||||
}
|
||||
]
|
||||
code: code || "BASE_TYPE_INVALID",
|
||||
},
|
||||
],
|
||||
}))
|
||||
);
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@ export class Rights extends BitField {
|
||||
INVITE_USERS: BitFlag(29), // can create user-specific invites in the guilds that they have INVITE_USERS
|
||||
SELF_DELETE_DISABLE: BitFlag(30), // can disable/delete own account
|
||||
DEBTABLE: BitFlag(31), // can use pay-to-use features
|
||||
CREDITABLE: BitFlag(32) // can receive money from monetisation related features
|
||||
CREDITABLE: BitFlag(32), // can receive money from monetisation related features
|
||||
};
|
||||
|
||||
any(permission: RightResolvable, checkOperator = true) {
|
||||
|
||||
Reference in new issue
Block a user