Merge branch 'master' of https://github.com/fosscord/fosscord-server
This commit is contained in:
		
						commit
						09c3d7a560
					
				| @ -1,4 +1,4 @@ | ||||
| import { emitEvent, getPermission, MessageAckEvent, ReadState } from "@fosscord/util"; | ||||
| import { emitEvent, getPermission, MessageAckEvent, ReadState, Snowflake } from "@fosscord/util"; | ||||
| import { Request, Response, Router } from "express"; | ||||
| import { route } from "@fosscord/api"; | ||||
| 
 | ||||
| @ -18,7 +18,11 @@ router.post("/", route({ body: "MessageAcknowledgeSchema" }), async (req: Reques | ||||
| 	const permission = await getPermission(req.user_id, undefined, channel_id); | ||||
| 	permission.hasThrow("VIEW_CHANNEL"); | ||||
| 
 | ||||
| 	await ReadState.update({ user_id: req.user_id, channel_id }, { user_id: req.user_id, channel_id, last_message_id: message_id }); | ||||
| 	let read_state = await ReadState.findOne({ user_id: req.user_id, channel_id }); | ||||
| 	if (!read_state) read_state = new ReadState({ user_id: req.user_id, channel_id }); | ||||
| 	read_state.last_message_id = message_id; | ||||
| 
 | ||||
| 	await read_state.save(); | ||||
| 
 | ||||
| 	await emitEvent({ | ||||
| 		event: "MESSAGE_ACK", | ||||
|  | ||||
| @ -103,6 +103,7 @@ router.get("/", async (req: Request, res: Response) => { | ||||
| 	} | ||||
| 
 | ||||
| 	const messages = await Message.find(query); | ||||
| 	const endpoint = Config.get().cdn.endpointPublic; | ||||
| 
 | ||||
| 	return res.json( | ||||
| 		messages.map((x) => { | ||||
| @ -115,7 +116,9 @@ router.get("/", async (req: Request, res: Response) => { | ||||
| 			// @ts-ignore
 | ||||
| 			if (!x.author) x.author = { discriminator: "0000", username: "Deleted User", public_flags: "0", avatar: null }; | ||||
| 			x.attachments?.forEach((x) => { | ||||
| 				x.proxy_url = `${Config.get().cdn.endpointPublic || "http://localhost:3003"}${new URL(x.proxy_url).pathname}`; | ||||
| 				// dynamically set attachment proxy_url in case the endpoint changed
 | ||||
| 				const uri = x.proxy_url.startsWith("http") ? x.proxy_url : `https://example.org${x.proxy_url}`; | ||||
| 				x.proxy_url = `${endpoint == null ? "http://localhost:3003" : endpoint}${new URL(uri).pathname}`; | ||||
| 			}); | ||||
| 
 | ||||
| 			return x; | ||||
|  | ||||
| @ -30,9 +30,6 @@ async function main() { | ||||
| 		cdn: { | ||||
| 			endpointClient: "${location.host}", | ||||
| 			endpointPrivate: `http://localhost:${port}`, | ||||
| 			...(!Config.get().cdn.endpointPublic && { | ||||
| 				endpointPublic: `http://localhost:${port}`, | ||||
| 			}), | ||||
| 		}, | ||||
| 		gateway: { | ||||
| 			endpointClient: | ||||
|  | ||||
| @ -11,6 +11,7 @@ import { | ||||
| 	PublicMember, | ||||
| 	PublicUser, | ||||
| 	PrivateUserProjection, | ||||
| 	ReadState, | ||||
| } from "@fosscord/util"; | ||||
| import { Send } from "../util/Send"; | ||||
| import { CLOSECODES, OPCODES } from "../util/Constants"; | ||||
| @ -138,6 +139,13 @@ export async function onIdentify(this: WebSocket, data: Payload) { | ||||
| 	//We save the session and we delete it when the websocket is closed
 | ||||
| 	await session.save(); | ||||
| 
 | ||||
| 	const read_states = await ReadState.find({ user_id: this.user_id }); | ||||
| 	read_states.forEach((s: any) => { | ||||
| 		s.id = s.channel_id; | ||||
| 		delete s.user_id; | ||||
| 		delete s.channel_id; | ||||
| 	}); | ||||
| 
 | ||||
| 	const privateUser = { | ||||
| 		avatar: user.avatar, | ||||
| 		mobile: user.mobile, | ||||
| @ -176,8 +184,7 @@ export async function onIdentify(this: WebSocket, data: Payload) { | ||||
| 		geo_ordered_rtc_regions: [], // TODO
 | ||||
| 		relationships: user.relationships.map((x) => x.toPublicRelationship()), | ||||
| 		read_state: { | ||||
| 			// TODO
 | ||||
| 			entries: [], | ||||
| 			entries: read_states, | ||||
| 			partial: false, | ||||
| 			version: 304128, | ||||
| 		}, | ||||
|  | ||||
| @ -1,4 +1,4 @@ | ||||
| import { Column, Entity, JoinColumn, ManyToOne, RelationId } from "typeorm"; | ||||
| import { Column, Entity, Index, JoinColumn, ManyToOne, RelationId } from "typeorm"; | ||||
| import { BaseClass } from "./BaseClass"; | ||||
| import { Channel } from "./Channel"; | ||||
| import { Message } from "./Message"; | ||||
| @ -9,8 +9,9 @@ import { User } from "./User"; | ||||
| // public read receipt ≥ notification cursor ≥ private fully read marker
 | ||||
| 
 | ||||
| @Entity("read_states") | ||||
| @Index(["channel_id", "user_id"], { unique: true }) | ||||
| export class ReadState extends BaseClass { | ||||
| 	@Column({ nullable: true }) | ||||
| 	@Column() | ||||
| 	@RelationId((read_state: ReadState) => read_state.channel) | ||||
| 	channel_id: string; | ||||
| 
 | ||||
| @ -20,7 +21,7 @@ export class ReadState extends BaseClass { | ||||
| 	}) | ||||
| 	channel: Channel; | ||||
| 
 | ||||
| 	@Column({ nullable: true }) | ||||
| 	@Column() | ||||
| 	@RelationId((read_state: ReadState) => read_state.user) | ||||
| 	user_id: string; | ||||
| 
 | ||||
| @ -35,15 +36,15 @@ export class ReadState extends BaseClass { | ||||
| 	last_message_id: string; | ||||
| 
 | ||||
| 	@JoinColumn({ name: "last_message_id" }) | ||||
| 	@ManyToOne(() => Message) | ||||
| 	@ManyToOne(() => Message, { nullable: true }) | ||||
| 	last_message?: Message; | ||||
| 
 | ||||
| 	@Column({ nullable: true }) | ||||
| 	last_pin_timestamp?: Date; | ||||
| 
 | ||||
| 	@Column() | ||||
| 	@Column({ nullable: true }) | ||||
| 	mention_count: number; | ||||
| 
 | ||||
| 	@Column() | ||||
| 	@Column({ nullable: true }) | ||||
| 	manual: boolean; | ||||
| } | ||||
|  | ||||
| @ -12,7 +12,6 @@ export const Config = { | ||||
| 		if (config) return config; | ||||
| 		pairs = await ConfigEntity.find(); | ||||
| 		config = pairsToConfig(pairs); | ||||
| 		console.log(config.guild.autoJoin); | ||||
| 
 | ||||
| 		return this.set((config || {}).merge(DefaultConfigOptions)); | ||||
| 	}, | ||||
|  | ||||
| @ -25,15 +25,30 @@ export async function uploadFile(path: string, file: Express.Multer.File) { | ||||
| 	return result; | ||||
| } | ||||
| 
 | ||||
| export async function handleFile(path: string, body?: string): Promise<string | undefined> { | ||||
| 	if (!body || !body.startsWith("data:")) return body; | ||||
| export async function handleFile( | ||||
| 	path: string, | ||||
| 	body?: string | ||||
| ): Promise< | ||||
| 	| (string & { | ||||
| 			id: string; | ||||
| 			content_type: string; | ||||
| 			size: number; | ||||
| 			url: string; | ||||
| 	  }) | ||||
| 	| undefined | ||||
| > { | ||||
| 	if (!body || !body.startsWith("data:")) return undefined; | ||||
| 	try { | ||||
| 		const mimetype = body.split(":")[1].split(";")[0]; | ||||
| 		const buffer = Buffer.from(body.split(",")[1], "base64"); | ||||
| 
 | ||||
| 		// @ts-ignore
 | ||||
| 		const { id } = await uploadFile(path, { buffer, mimetype, originalname: "banner" }); | ||||
| 		return id; | ||||
| 		const file = await uploadFile(path, { buffer, mimetype, originalname: "banner" }); | ||||
| 		const obj = file.id; | ||||
| 		for (const key in file) { | ||||
| 			obj[key] = file[key]; | ||||
| 		} | ||||
| 		return obj; | ||||
| 	} catch (error) { | ||||
| 		console.error(error); | ||||
| 		throw new HTTPError("Invalid " + path); | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 uurgothat
						uurgothat