Fix websocket to websockets global variable references to support ng

This commit is contained in:
SrGooglo 2025-04-24 06:10:50 +00:00
parent 7b7e7b9bb7
commit 1f0c1d5033
23 changed files with 214 additions and 208 deletions

View File

@ -89,11 +89,15 @@ export default async (payload = {}, req) => {
// broadcast post to all users // broadcast post to all users
if (visibility === "public") { if (visibility === "public") {
global.websocket.senders.toTopic("realtime:feed", "post:new", result[0]) global.websockets.senders.toTopic(
"realtime:feed",
"post:new",
result[0],
)
} }
if (visibility === "private") { if (visibility === "private") {
const userSockets = await global.websocket.find.clientsByUserId( const userSockets = await global.websockets.find.clientsByUserId(
post.user_id, post.user_id,
) )

View File

@ -42,7 +42,7 @@ export default async (payload = {}) => {
// broadcast post to all users // broadcast post to all users
if (post.visibility === "public") { if (post.visibility === "public") {
global.websocket.senders.toTopic( global.websockets.senders.toTopic(
"realtime:feed", "realtime:feed",
"post:delete", "post:delete",
post_id, post_id,
@ -50,7 +50,7 @@ export default async (payload = {}) => {
} }
if (post.visibility === "private") { if (post.visibility === "private") {
const userSockets = await global.websocket.find.clientsByUserId( const userSockets = await global.websockets.find.clientsByUserId(
post.user_id, post.user_id,
) )

View File

@ -1,33 +1,33 @@
import { VotePoll } from "@db_models" import { VotePoll } from "@db_models"
export default async (payload = {}) => { export default async (payload = {}) => {
if (!payload.user_id) { if (!payload.user_id) {
throw new OperationError(400, "Missing user_id") throw new OperationError(400, "Missing user_id")
} }
if (!payload.post_id) { if (!payload.post_id) {
throw new OperationError(400, "Missing post_id") throw new OperationError(400, "Missing post_id")
} }
if (!payload.option_id) { if (!payload.option_id) {
throw new OperationError(400, "Missing option_id") throw new OperationError(400, "Missing option_id")
} }
let vote = await VotePoll.find({ let vote = await VotePoll.find({
user_id: payload.user_id, user_id: payload.user_id,
post_id: payload.post_id, post_id: payload.post_id,
option_id: payload.option_id, option_id: payload.option_id,
}) })
if (!vote) { if (!vote) {
throw new OperationError(404, "Poll vote not found") throw new OperationError(404, "Poll vote not found")
} }
await VotePoll.deleteOne({ await VotePoll.deleteOne({
_id: vote._id _id: vote._id,
}) })
global.websocket.io.of("/").emit(`post.poll.vote.deleted`, vote) global.websockets.io.of("/").emit(`post.poll.vote.deleted`, vote)
return vote return vote
} }

View File

@ -37,7 +37,7 @@ export default async (post_id, update) => {
}) })
if (post.visibility === "public") { if (post.visibility === "public") {
global.websocket.senders.toTopic( global.websockets.senders.toTopic(
"realtime:feed", "realtime:feed",
`post:update`, `post:update`,
result[0], result[0],
@ -45,7 +45,7 @@ export default async (post_id, update) => {
} }
if (post.visibility === "private") { if (post.visibility === "private") {
const userSockets = await global.websocket.find.clientsByUserId( const userSockets = await global.websockets.find.clientsByUserId(
post.user_id, post.user_id,
) )

View File

@ -51,7 +51,7 @@ export default async (payload = {}) => {
post = (await stage({ posts: post, for_user_id: payload.user_id }))[0] post = (await stage({ posts: post, for_user_id: payload.user_id }))[0]
if (post.visibility === "public") { if (post.visibility === "public") {
global.websocket.senders.toTopic("realtime:feed", `post:update`, post) global.websockets.senders.toTopic("realtime:feed", `post:update`, post)
} }
return { return {

View File

View File

@ -1,5 +1,5 @@
//import { Server } from "../../../../linebridge/server/src" import { Server } from "../../../../linebridge/server/src"
import { Server } from "linebridge" //import { Server } from "linebridge"
import DbManager from "@shared-classes/DbManager" import DbManager from "@shared-classes/DbManager"
import RedisClient from "@shared-classes/RedisClient" import RedisClient from "@shared-classes/RedisClient"
@ -10,10 +10,11 @@ import SharedMiddlewares from "@shared-middlewares"
export default class API extends Server { export default class API extends Server {
static refName = "posts" static refName = "posts"
static useEngine = "hyper-express-ng" //static useEngine = "hyper-express-ng"
static enableWebsockets = true static websockets = true
static listenPort = process.env.HTTP_LISTEN_PORT ?? 3001
static listen_port = process.env.HTTP_LISTEN_PORT ?? 3001 // static useMiddlewares = ["logs"]
static bypassCors = true
middlewares = { middlewares = {
...SharedMiddlewares, ...SharedMiddlewares,

View File

@ -1,13 +1,13 @@
import Posts from "@classes/posts" import Posts from "@classes/posts"
export default { export default {
middlewares: ["withOptionalAuthentication"], useMiddlewares: ["withOptionalAuthentication"],
fn: async (req, res) => { fn: async (req, res) => {
const result = await Posts.data({ const result = await Posts.data({
post_id: req.params.post_id, post_id: req.params.post_id,
for_user_id: req.auth?.session?.user_id, for_user_id: req.auth?.session?.user_id,
}) })
return result return result
} },
} }

View File

@ -1,27 +1,28 @@
import PostClass from "@classes/posts" import PostClass from "@classes/posts"
import { Post } from "@db_models" import { Post } from "@db_models"
export default { export default {
middlewares: ["withAuthentication"], useMiddlewares: ["withAuthentication"],
fn: async (req, res) => { fn: async (req, res) => {
// check if post is owned or if is admin // check if post is owned or if is admin
const post = await Post.findById(req.params.post_id).catch(() => { const post = await Post.findById(req.params.post_id).catch(() => {
return false return false
}) })
if (!post) { if (!post) {
throw new OperationError(404, "Post not found") throw new OperationError(404, "Post not found")
} }
const user = await req.auth.user() const user = await req.auth.user()
if (post.user_id.toString() !== user._id.toString()) { if (post.user_id.toString() !== user._id.toString()) {
if (!user.roles.includes("admin")) { if (!user.roles.includes("admin")) {
throw new OperationError(403, "You cannot delete this post") throw new OperationError(403, "You cannot delete this post")
} }
} }
return await PostClass.delete({ return await PostClass.delete({
post_id: req.params.post_id post_id: req.params.post_id,
}) })
} },
} }

View File

@ -1,13 +1,13 @@
import PostClass from "@classes/posts" import PostClass from "@classes/posts"
export default { export default {
middlewares: ["withOptionalAuthentication"], useMiddlewares: ["withOptionalAuthentication"],
fn: async (req) => { fn: async (req) => {
return await PostClass.replies({ return await PostClass.replies({
post_id: req.params.post_id, post_id: req.params.post_id,
for_user_id: req.auth?.session.user_id, for_user_id: req.auth?.session.user_id,
trim: req.query.trim, trim: req.query.trim,
limit: req.query.limit limit: req.query.limit,
}) })
} },
} }

View File

@ -1,14 +1,14 @@
import Posts from "@classes/posts" import Posts from "@classes/posts"
export default { export default {
middlewares: ["withAuthentication"], useMiddlewares: ["withAuthentication"],
fn: async (req, res) => { fn: async (req, res) => {
const result = await Posts.toggleLike({ const result = await Posts.toggleLike({
post_id: req.params.post_id, post_id: req.params.post_id,
user_id: req.auth.session.user_id, user_id: req.auth.session.user_id,
to: req.body?.to, to: req.body?.to,
}) })
return result return result
} },
} }

View File

@ -1,14 +1,14 @@
import Posts from "@classes/posts" import Posts from "@classes/posts"
export default { export default {
middlewares: ["withAuthentication"], useMiddlewares: ["withAuthentication"],
fn: async (req, res) => { fn: async (req, res) => {
const result = await Posts.toggleSave({ const result = await Posts.toggleSave({
post_id: req.params.post_id, post_id: req.params.post_id,
user_id: req.auth.session.user_id, user_id: req.auth.session.user_id,
to: req.body?.to, to: req.body?.to,
}) })
return result return result
} },
} }

View File

@ -15,7 +15,7 @@ const MaxStringsLengths = {
} }
export default { export default {
middlewares: ["withAuthentication"], useMiddlewares: ["withAuthentication"],
fn: async (req) => { fn: async (req) => {
let update = {} let update = {}

View File

@ -1,14 +1,14 @@
import Posts from "@classes/posts" import Posts from "@classes/posts"
export default { export default {
middlewares: ["withAuthentication"], useMiddlewares: ["withAuthentication"],
fn: async (req) => { fn: async (req) => {
const result = await Posts.deleteVotePoll({ const result = await Posts.deleteVotePoll({
user_id: req.auth.session.user_id, user_id: req.auth.session.user_id,
post_id: req.params.post_id, post_id: req.params.post_id,
option_id: req.params.option_id, option_id: req.params.option_id,
}) })
return result return result
} },
} }

View File

@ -1,14 +1,14 @@
import Posts from "@classes/posts" import Posts from "@classes/posts"
export default { export default {
middlewares: ["withAuthentication"], useMiddlewares: ["withAuthentication"],
fn: async (req) => { fn: async (req) => {
const result = await Posts.votePoll({ const result = await Posts.votePoll({
user_id: req.auth.session.user_id, user_id: req.auth.session.user_id,
post_id: req.params.post_id, post_id: req.params.post_id,
option_id: req.params.option_id, option_id: req.params.option_id,
}) })
return result return result
} },
} }

View File

@ -1,19 +1,19 @@
import Posts from "@classes/posts" import Posts from "@classes/posts"
export default { export default {
middlewares: ["withOptionalAuthentication"], useMiddlewares: ["withOptionalAuthentication"],
fn: async (req, res) => { fn: async (req, res) => {
const payload = { const payload = {
limit: req.query?.limit, limit: req.query?.limit,
trim: req.query?.trim, trim: req.query?.trim,
} }
if (req.auth) { if (req.auth) {
payload.user_id = req.auth.session.user_id payload.user_id = req.auth.session.user_id
} }
const result = await Posts.globalTimeline(payload) const result = await Posts.globalTimeline(payload)
return result return result
} },
} }

View File

@ -1,19 +1,19 @@
import Posts from "@classes/posts" import Posts from "@classes/posts"
export default { export default {
middlewares: ["withOptionalAuthentication"], useMiddlewares: ["withOptionalAuthentication"],
fn: async (req, res) => { fn: async (req, res) => {
const payload = { const payload = {
limit: req.query?.limit, limit: req.query?.limit,
trim: req.query?.trim, trim: req.query?.trim,
} }
if (req.auth) { if (req.auth) {
payload.user_id = req.auth.session.user_id payload.user_id = req.auth.session.user_id
} }
const result = await Posts.timeline(payload) const result = await Posts.timeline(payload)
return result return result
} },
} }

View File

@ -1,12 +1,12 @@
import Posts from "@classes/posts" import Posts from "@classes/posts"
export default { export default {
middlewares: ["withAuthentication"], useMiddlewares: ["withAuthentication"],
fn: async (req) => { fn: async (req) => {
return await Posts.getLiked({ return await Posts.getLiked({
trim: req.query.trim, trim: req.query.trim,
limit: req.query.limit, limit: req.query.limit,
user_id: req.auth.session.user_id user_id: req.auth.session.user_id,
}) })
} },
} }

View File

@ -1,7 +1,7 @@
import Posts from "@classes/posts" import Posts from "@classes/posts"
export default { export default {
middlewares: ["withAuthentication"], useMiddlewares: ["withAuthentication"],
fn: async (req, res) => { fn: async (req, res) => {
const result = await Posts.create( const result = await Posts.create(
{ {

View File

@ -1,12 +1,12 @@
import Posts from "@classes/posts" import Posts from "@classes/posts"
export default { export default {
middlewares: ["withAuthentication"], useMiddlewares: ["withAuthentication"],
fn: async (req) => { fn: async (req) => {
return await Posts.getSaved({ return await Posts.getSaved({
trim: req.query.trim, trim: req.query.trim,
limit: req.query.limit, limit: req.query.limit,
user_id: req.auth.session.user_id user_id: req.auth.session.user_id,
}) })
} },
} }

View File

@ -2,7 +2,7 @@ import { Post } from "@db_models"
import stage from "@classes/posts/methods/stage" import stage from "@classes/posts/methods/stage"
export default { export default {
middlewares: ["withOptionalAuthentication"], useMiddlewares: ["withOptionalAuthentication"],
fn: async (req) => { fn: async (req) => {
const { limit, trim } = req.query const { limit, trim } = req.query

View File

@ -5,41 +5,41 @@ const maxDaysOld = 30
const maxHashtags = 5 const maxHashtags = 5
export default async (req) => { export default async (req) => {
// fetch all posts that contain in message an #, with a maximun of 5 diferent hashtags // fetch all posts that contain in message an #, with a maximun of 5 diferent hashtags
const startDate = DateTime.local().minus({ days: maxDaysOld }).toISO() const startDate = DateTime.local().minus({ days: maxDaysOld }).toISO()
const trendings = await Post.aggregate([ const trendings = await Post.aggregate([
{ {
$match: { $match: {
message: { $regex: /#/gi }, message: { $regex: /#/gi },
created_at: { $gte: startDate } created_at: { $gte: startDate },
} },
}, },
{ {
$project: { $project: {
hashtags: { hashtags: {
$regexFindAll: { $regexFindAll: {
input: "$message", input: "$message",
regex: /#[a-zA-Z0-9_]+/g regex: /#[a-zA-Z0-9_]+/g,
} },
} },
} },
}, },
{ $unwind: "$hashtags" }, { $unwind: "$hashtags" },
{ {
$project: { $project: {
hashtag: { $substr: ["$hashtags.match", 1, -1] } hashtag: { $substr: ["$hashtags.match", 1, -1] },
} },
}, },
{ {
$group: { $group: {
_id: "$hashtag", _id: "$hashtag",
count: { $sum: 1 } count: { $sum: 1 },
} },
}, },
{ $sort: { count: -1 } }, { $sort: { count: -1 } },
{ $limit: maxHashtags } { $limit: maxHashtags },
]) ])
return trendings.map(({ _id, count }) => ({ hashtag: _id, count })); return trendings.map(({ _id, count }) => ({ hashtag: _id, count }))
} }

View File

@ -1,13 +1,13 @@
import Posts from "@classes/posts" import Posts from "@classes/posts"
export default { export default {
middlewares: ["withOptionalAuthentication"], useMiddlewares: ["withOptionalAuthentication"],
fn: async (req, res) => { fn: async (req, res) => {
return await Posts.fromUserId({ return await Posts.fromUserId({
skip: req.query.skip, skip: req.query.skip,
trim: req.query.trim, trim: req.query.trim,
user_id: req.params.user_id, user_id: req.params.user_id,
for_user_id: req.auth?.session?.user_id, for_user_id: req.auth?.session?.user_id,
}) })
} },
} }