diff --git a/packages/app/src/pages/lyrics/components/controller/index.jsx b/packages/app/src/pages/lyrics/components/controller/index.jsx
index 85e21477..5018317b 100644
--- a/packages/app/src/pages/lyrics/components/controller/index.jsx
+++ b/packages/app/src/pages/lyrics/components/controller/index.jsx
@@ -64,6 +64,7 @@ const PlayerController = React.forwardRef((props, ref) => {
setDraggingTime(false)
app.cores.player.seek(seekTime)
+
syncPlayback()
}
@@ -91,7 +92,6 @@ const PlayerController = React.forwardRef((props, ref) => {
React.useEffect(() => {
setTitleIsOverflown(isOverflown(titleRef.current))
setTrackDuration(app.cores.player.duration())
- console.log(context.track_manifest)
}, [context.track_manifest])
React.useEffect(() => {
@@ -104,7 +104,7 @@ const PlayerController = React.forwardRef((props, ref) => {
className={classnames(
"lyrics-player-controller-wrapper",
{
- ["hidden"]: hide,
+ ["hidden"]: props.lyrics?.video_source && hide,
}
)}
onMouseEnter={onMouseEnter}
diff --git a/packages/app/src/pages/lyrics/index.jsx b/packages/app/src/pages/lyrics/index.jsx
index 96cfa840..54c9ef69 100644
--- a/packages/app/src/pages/lyrics/index.jsx
+++ b/packages/app/src/pages/lyrics/index.jsx
@@ -25,10 +25,14 @@ const EnchancedLyrics = (props) => {
async function loadLyrics(track_id) {
const result = await MusicService.getTrackLyrics(track_id, {
preferTranslation: translationEnabled,
+ }).catch((err) => {
+ return null
})
if (result) {
setLyrics(result)
+ } else {
+ setLyrics(false)
}
}
@@ -49,7 +53,7 @@ const EnchancedLyrics = (props) => {
//* Handle when context change track_manifest
React.useEffect(() => {
setLyrics(null)
-
+
if (context.track_manifest) {
loadLyrics(context.track_manifest._id)
}
@@ -72,6 +76,20 @@ const EnchancedLyrics = (props) => {
}
)}
>
+ {
+ !lyrics?.video_source &&
+
+

+
+
+ }
+
{
isRemoteTyping,
} = useChat(to_user_id)
-
console.log(R_User)
async function submitMessage(e) {
diff --git a/packages/app/src/pages/messages/index.jsx b/packages/app/src/pages/messages/index.jsx
index 1a75f763..38d30642 100644
--- a/packages/app/src/pages/messages/index.jsx
+++ b/packages/app/src/pages/messages/index.jsx
@@ -1,7 +1,6 @@
import React from "react"
import * as antd from "antd"
-
import ChatsService from "@models/chats"
import TimeAgo from "@components/TimeAgo"
diff --git a/packages/app/src/pages/nfc/[tag_id].jsx b/packages/app/src/pages/nfc/[tag_id].jsx
index f81ed6c5..47630277 100755
--- a/packages/app/src/pages/nfc/[tag_id].jsx
+++ b/packages/app/src/pages/nfc/[tag_id].jsx
@@ -27,6 +27,13 @@ export default (props) => {
case "profile": {
return app.navigation.goToAccount(result.behavior.value)
}
+ case "random_list": {
+ const values = result.behavior.value.split(";")
+
+ const index = Math.floor(Math.random() * values.length)
+
+ return window.location.href = values[index]
+ }
}
}
diff --git a/packages/app/src/settings/about/index.jsx b/packages/app/src/settings/about/index.jsx
index 4e7966ef..348273bb 100755
--- a/packages/app/src/settings/about/index.jsx
+++ b/packages/app/src/settings/about/index.jsx
@@ -1,7 +1,7 @@
import React from "react"
import * as antd from "antd"
-import { version as linebridgeVersion } from "linebridge/package.json"
+// import { version as linebridgeVersion } from "linebridge/package.json"
import { Icons } from "@components/Icons"
import LatencyIndicator from "@components/PerformanceIndicators/latency"
@@ -157,6 +157,20 @@ export default {
+
+
+
+
+ {Capacitor.platform}
+
+
+
@@ -177,21 +191,7 @@ export default {
-
Linebridge Engine
-
-
-
- {linebridgeVersion ?? globalThis._linebrige_version ?? "Unknown"}
-
-
-
-
-
-
-
-
-
-
Evite Framework
+
Engine
@@ -205,7 +205,7 @@ export default {
-
Comty.JS
+
Comty.js
@@ -213,20 +213,6 @@ export default {
-
-
-
-
- {Capacitor.platform}
-
-
-
{
capInfo &&
diff --git a/packages/app/src/settings/api/index.jsx b/packages/app/src/settings/api/index.jsx
new file mode 100644
index 00000000..6ef90cd0
--- /dev/null
+++ b/packages/app/src/settings/api/index.jsx
@@ -0,0 +1,81 @@
+import React from "react"
+import * as antd from "antd"
+
+import "./index.less"
+
+const useGetMainOrigin = () => {
+ const [mainOrigin, setMainOrigin] = React.useState(null)
+
+ React.useEffect(() => {
+ const instance = app.cores.api.client()
+
+ if (instance) {
+ setMainOrigin(instance.mainOrigin)
+ }
+
+ return () => {
+ setMainOrigin(null)
+ }
+ }, [])
+
+ return mainOrigin
+}
+
+export default {
+ id: "api",
+ icon: "TbApi",
+ label: "API",
+ group: "advanced",
+ render: () => {
+ const mainOrigin = useGetMainOrigin()
+ const [keys, setKeys] = React.useState([])
+
+ return
+
+
+ Main Origin
+
+
+ {mainOrigin}
+
+
+
+
+
+
+
Your Keys
+
Manage your API keys
+
+
+
+ Create new
+
+
+
+
+ {
+ keys.map((key) => {
+ return null
+ })
+ }
+ {
+ keys.length === 0 &&
+ }
+
+
+
+
+
+ }
+}
\ No newline at end of file
diff --git a/packages/app/src/settings/api/index.less b/packages/app/src/settings/api/index.less
new file mode 100644
index 00000000..77874408
--- /dev/null
+++ b/packages/app/src/settings/api/index.less
@@ -0,0 +1,32 @@
+.developer-settings {
+ display: flex;
+ flex-direction: column;
+
+ gap: 20px;
+}
+
+.api_keys {
+ display: flex;
+ flex-direction: column;
+
+ background-color: var(--background-color-accent);
+
+ padding: 10px;
+
+ border-radius: 12px;
+
+ .api_keys_header {
+ display: flex;
+ flex-direction: row;
+
+ align-items: center;
+ justify-content: space-between;
+ }
+}
+
+.links {
+ display: flex;
+ flex-direction: column;
+
+ gap: 5px;
+}
\ No newline at end of file
diff --git a/packages/app/src/settings/apparence/index.jsx b/packages/app/src/settings/apparence/index.jsx
index 8dfdb5f9..d830679e 100755
--- a/packages/app/src/settings/apparence/index.jsx
+++ b/packages/app/src/settings/apparence/index.jsx
@@ -14,7 +14,6 @@ export default {
{
id: "style:variant_mode",
group: "aspect",
- component: "Switch",
icon: "Moon",
title: "Theme",
description: "Change the theme of the application.",
@@ -52,7 +51,7 @@ export default {
max: 1.2,
step: 0.01,
tooltip: {
- formatter: (value) => `${value}x`
+ formatter: (value) => `x${value}`
}
},
defaultValue: () => {
@@ -143,8 +142,6 @@ export default {
defaultValue: () => {
const value = app.cores.style.getVar("backgroundImage")
- console.log(value)
-
return value ? value.replace(/url\(|\)/g, "") : ""
},
onUpdate: (value) => {
diff --git a/packages/app/src/settings/changelogs/index.jsx b/packages/app/src/settings/changelogs/index.jsx
index 84300ee0..143ab605 100755
--- a/packages/app/src/settings/changelogs/index.jsx
+++ b/packages/app/src/settings/changelogs/index.jsx
@@ -14,7 +14,7 @@ import "./index.less"
const FetchChangelogs = async () => {
const response = await app.cores.api.customRequest({
method: "GET",
- url: `/release-notes`,
+ url: `/repo/releases-notes`,
})
return response.data
diff --git a/packages/app/src/settings/components/changePassword/index.jsx b/packages/app/src/settings/components/changePassword/index.jsx
index 8ffa03c2..852a2d3e 100755
--- a/packages/app/src/settings/components/changePassword/index.jsx
+++ b/packages/app/src/settings/components/changePassword/index.jsx
@@ -125,11 +125,7 @@ const ChangePasswordComponent = (props) => {
export default (props) => {
const onClick = () => {
- if (app.isMobile) {
- return app.layout.drawer.open("passwordChange", ChangePasswordComponent)
- }
-
- return app.layout.sidedrawer.open("passwordChange", ChangePasswordComponent)
+ return app.layout.drawer.open("passwordChange", ChangePasswordComponent)
}
return
diff --git a/packages/app/src/settings/components/themeVariantSelector/index.less b/packages/app/src/settings/components/themeVariantSelector/index.less
index 8f8cc413..4e33e528 100644
--- a/packages/app/src/settings/components/themeVariantSelector/index.less
+++ b/packages/app/src/settings/components/themeVariantSelector/index.less
@@ -7,6 +7,8 @@
border: 1px var(--border-color) solid;
border-radius: 12px;
+ width: fit-content;
+
overflow: hidden;
.__setting_theme_variant_selector-variant {
diff --git a/packages/app/src/settings/general/index.jsx b/packages/app/src/settings/general/index.jsx
index a1922d80..a3e139c1 100755
--- a/packages/app/src/settings/general/index.jsx
+++ b/packages/app/src/settings/general/index.jsx
@@ -60,7 +60,7 @@ export default {
group: "ui.sounds",
component: "Switch",
icon: "MdVolumeUp",
- title: "UI effects",
+ title: "Effects",
description: "Enable the UI effects.",
mobile: false,
},
@@ -70,8 +70,8 @@ export default {
group: "ui.sounds",
component: "Slider",
icon: "MdVolumeUp",
- title: "UI volume",
- description: "Set the volume of the app sounds.",
+ title: "Volume",
+ description: "Set the volume of the app UI sounds.",
props: {
tipFormatter: (value) => {
return `${value}%`
@@ -108,7 +108,7 @@ export default {
group: "notifications",
component: "Slider",
icon: "MdVolumeUp",
- title: "Sound Volume",
+ title: "Volume",
description: "Set the volume of the sound when a notification is received.",
props: {
tipFormatter: (value) => {
diff --git a/packages/app/src/settings/tap_share/index.jsx b/packages/app/src/settings/tap_share/index.jsx
index 7f1a2c60..0dcdf9e8 100755
--- a/packages/app/src/settings/tap_share/index.jsx
+++ b/packages/app/src/settings/tap_share/index.jsx
@@ -152,7 +152,7 @@ const TagItem = (props) => {
}
danger
- disabled
+ onClick={props.onDelete}
/>
@@ -192,6 +192,25 @@ class OwnTags extends React.Component {
})
}
+ handleTagDelete = (tag) => {
+ antd.Modal.confirm({
+ title: "Are you sure you want to delete this tag?",
+ content: `This action cannot be undone.`,
+ onOk: async () => {
+ NFCModel.deleteTag(tag._id)
+ .then(() => {
+ app.message.success("Tag deleted")
+ this.loadData()
+ })
+ .catch((err) => {
+ console.error(err)
+ app.message.error(err.message)
+ return false
+ })
+ }
+ })
+ }
+
handleTagRead = async (error, tag) => {
if (error) {
console.error(error)
@@ -252,6 +271,9 @@ class OwnTags extends React.Component {
tag
})
}}
+ onDelete={() => {
+ this.handleTagDelete(tag)
+ }}
/>
})
}
diff --git a/packages/app/src/settings/tap_share/steps/data_editor/index.jsx b/packages/app/src/settings/tap_share/steps/data_editor/index.jsx
index c3bcd946..1d90098e 100755
--- a/packages/app/src/settings/tap_share/steps/data_editor/index.jsx
+++ b/packages/app/src/settings/tap_share/steps/data_editor/index.jsx
@@ -137,9 +137,9 @@ export default (props) => {
- Post
+ Random list
diff --git a/packages/app/src/styles/index.less b/packages/app/src/styles/index.less
index af35fb8f..bba8c028 100755
--- a/packages/app/src/styles/index.less
+++ b/packages/app/src/styles/index.less
@@ -331,4 +331,17 @@ svg {
}
}
}
+}
+
+.card {
+ display: flex;
+ flex-direction: column;
+
+ background-color: var(--background-color-accent);
+
+ padding: 10px;
+
+ border-radius: 12px;
+
+ gap: 10px;
}
\ No newline at end of file
diff --git a/packages/app/vite.config.js b/packages/app/vite.config.js
index 050a4670..fac87fc1 100755
--- a/packages/app/vite.config.js
+++ b/packages/app/vite.config.js
@@ -1,23 +1,10 @@
import path from "path"
+import aliases from "./aliases"
import { defineConfig } from "vite"
import react from "@vitejs/plugin-react"
-const aliases = {
- "@": path.join(__dirname, "src"),
- "@config": path.join(__dirname, "config"),
- "@cores": path.join(__dirname, "src/cores"),
- "@pages": path.join(__dirname, "src/pages"),
- "@styles": path.join(__dirname, "src/styles"),
- "@components": path.join(__dirname, "src/components"),
- "@contexts": path.join(__dirname, "src/contexts"),
- "@utils": path.join(__dirname, "src/utils"),
- "@layouts": path.join(__dirname, "src/layouts"),
- "@hooks": path.join(__dirname, "src/hooks"),
- "@classes": path.join(__dirname, "src/classes"),
- "@models": path.join(__dirname, "../../", "comty.js/src/models"),
- "comty.js": path.join(__dirname, "../../", "comty.js", "src"),
-}
+const oneYearInSeconds = 60 * 60 * 24 * 365
export default defineConfig({
plugins: [
@@ -35,7 +22,10 @@ export default defineConfig({
https: {
key: path.join(__dirname, "ssl", "privkey.pem"),
cert: path.join(__dirname, "ssl", "cert.pem"),
- }
+ },
+ headers: {
+ "Strict-Transport-Security": `max-age=${oneYearInSeconds}`
+ },
},
css: {
preprocessorOptions: {
diff --git a/packages/server/.dockerignore b/packages/server/.dockerignore
new file mode 100644
index 00000000..571157e3
--- /dev/null
+++ b/packages/server/.dockerignore
@@ -0,0 +1,8 @@
+./node_modules
+./build
+./dist
+./ssl
+
+# secrets
+./api.production.env
+./.env
\ No newline at end of file
diff --git a/packages/server/.swcrc b/packages/server/.swcrc
new file mode 100644
index 00000000..4d32447a
--- /dev/null
+++ b/packages/server/.swcrc
@@ -0,0 +1,15 @@
+{
+ "$schema": "http://json.schemastore.org/swcrc",
+ "exclude":[
+ "node_modules/minio/**",
+ "node_modules/@octokit/**"
+ ],
+ "module": {
+ "type": "commonjs",
+ // These are defaults.
+ "strict": false,
+ "strictMode": true,
+ "lazy": false,
+ "noInterop": false
+ }
+}
\ No newline at end of file
diff --git a/packages/server/Dockerfile b/packages/server/Dockerfile
index 9305ff34..bfd8f6a8 100755
--- a/packages/server/Dockerfile
+++ b/packages/server/Dockerfile
@@ -1,27 +1,36 @@
-FROM node:16-bullseye-slim
+FROM node:18-bookworm-slim
+EXPOSE 9000
+# Install dependencies
RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list
-
RUN apt update
-RUN apt install --no-install-recommends curl ffmpeg python yarn build-essential -y
+RUN apt install -y --no-install-recommends build-essential
+RUN apt install -y --no-install-recommends curl
+RUN apt install -y --no-install-recommends ffmpeg
+RUN apt install -y --no-install-recommends yarn
+RUN apt install -y --no-install-recommends git
+RUN apt install -y --no-install-recommends ssh
+RUN apt install -y --no-install-recommends ca-certificates
-RUN mkdir -p /home/node/app/node_modules && chown -R node:node /home/node/app
+# Create workdir
+RUN mkdir -p /comty-server
+WORKDIR /comty-server
-WORKDIR /home/node/app
+# Copy Files
+COPY package.json ./
+COPY . .
+
+# Fix permissions
+RUN chmod -R 777 /comty-server
+RUN chown -R node:node /comty-server
+
+# Set user to node
USER node
-EXPOSE 3010
-
-COPY package.json ./
-COPY --chown=node:node . .
-
-RUN chmod -R 777 /home/node/app
-
-RUN export NODE_ENV=production
-
-RUN yarn global add cross-env
-RUN yarn install --production
-RUN yarn build
+# Install modules & rebuild for host
+RUN npm install
RUN npm rebuild @tensorflow/tfjs-node --build-from-source
-CMD ["yarn", "run", "run:prod"]
\ No newline at end of file
+# Start server
+RUN export NODE_ENV=production
+CMD ["npm", "run", "start:prod"]
\ No newline at end of file
diff --git a/packages/server/docker-compose.yml b/packages/server/docker-compose.yml
new file mode 100644
index 00000000..3f4c064e
--- /dev/null
+++ b/packages/server/docker-compose.yml
@@ -0,0 +1,11 @@
+services:
+ api:
+ container_name: comty-api
+ build: .
+ restart: unless-stopped
+ ports:
+ - "9000:9000"
+ env_file:
+ - ./api.production.env
+ volumes:
+ - ./ssl:/comty-server/ssl
\ No newline at end of file
diff --git a/packages/server/gateway/index.js b/packages/server/gateway/index.js
index dfcba1f8..2d5337fa 100644
--- a/packages/server/gateway/index.js
+++ b/packages/server/gateway/index.js
@@ -5,7 +5,7 @@ import Spinnies from "spinnies"
import { Observable } from "@gullerya/object-observer"
import { dots as DefaultSpinner } from "spinnies/spinners.json"
import EventEmitter from "@foxify/events"
-import IPCRouter from "linebridge/src/server/classes/IPCRouter"
+import IPCRouter from "linebridge/dist/server/classes/IPCRouter"
import chokidar from "chokidar"
import { onExit } from "signal-exit"
import chalk from "chalk"
diff --git a/packages/server/gateway/proxy.js b/packages/server/gateway/proxy.js
index 7dcaf4ab..76b1afee 100644
--- a/packages/server/gateway/proxy.js
+++ b/packages/server/gateway/proxy.js
@@ -1,5 +1,5 @@
import httpProxy from "http-proxy"
-import defaults from "linebridge/src/server/defaults"
+import defaults from "linebridge/dist/server/defaults"
import pkg from "../package.json"
diff --git a/packages/server/package.json b/packages/server/package.json
index 83eb7f33..b110698b 100755
--- a/packages/server/package.json
+++ b/packages/server/package.json
@@ -1,36 +1,54 @@
{
- "name": "@comty/server",
- "version": "0.70.0",
- "license": "MIT",
- "workspaces": [
- "services/*"
- ],
- "private": true,
- "scripts": {
- "build": "hermes build",
- "dev": "cross-env NODE_ENV=development hermes-node ./index.js",
- "run:prod": "cross-env NODE_ENV=production node ./dist/index.js"
- },
- "dependencies": {
- "@gullerya/object-observer": "^6.1.3",
- "@infisical/sdk": "^2.1.8",
- "@ragestudio/hermes": "^0.1.1",
- "chalk": "4.1.2",
- "dotenv": "^16.4.4",
- "http-proxy": "^1.18.1",
- "linebridge": "^0.18.1",
- "module-alias": "^2.2.3",
- "nodejs-snowflake": "^2.0.1",
- "signal-exit": "^4.1.0",
- "spinnies": "^0.5.1",
- "tree-kill": "^1.2.2"
- },
- "devDependencies": {
- "chai": "^5.1.0",
- "cross-env": "^7.0.3",
- "mocha": "^10.3.0"
- },
- "resolutions": {
- "string-width": "4.2.3"
- }
+ "name": "@comty/server",
+ "version": "0.70.0",
+ "license": "MIT",
+ "workspaces": [
+ "services/*"
+ ],
+ "private": true,
+ "scripts": {
+ "start:prod": "cross-env NODE_ENV=production hermes-node ./index.js",
+ "dev": "cross-env NODE_ENV=development hermes-node ./index.js",
+ "build:bin": "cd build && pkg ./index.js"
+ },
+ "dependencies": {
+ "@gullerya/object-observer": "^6.1.3",
+ "@infisical/sdk": "^2.1.8",
+ "@ragestudio/hermes": "^0.1.1",
+ "axios": "^1.7.4",
+ "bcrypt": "^5.1.1",
+ "chalk": "4.1.2",
+ "comty.js": "^0.60.3",
+ "dotenv": "^16.4.4",
+ "http-proxy": "^1.18.1",
+ "ioredis": "^5.4.1",
+ "jsonwebtoken": "^9.0.2",
+ "linebridge": "^0.20.3",
+ "minio": "^8.0.1",
+ "module-alias": "^2.2.3",
+ "mongoose": "^8.5.3",
+ "nodejs-snowflake": "^2.0.1",
+ "qs": "^6.13.0",
+ "signal-exit": "^4.1.0",
+ "spinnies": "^0.5.1",
+ "tree-kill": "^1.2.2"
+ },
+ "devDependencies": {
+ "@swc-node/register": "^1.10.9",
+ "@swc/cli": "^0.3.12",
+ "@swc/core": "^1.4.11",
+ "chai": "^5.1.0",
+ "cross-env": "^7.0.3",
+ "mocha": "^10.3.0",
+ "pkg": "^5.8.1"
+ },
+ "resolutions": {
+ "string-width": "4.2.3"
+ },
+ "pkg": {
+ "targets": [
+ "node18-linux-arm64"
+ ],
+ "outputPath": "dist"
+ }
}
diff --git a/packages/server/services/auth/auth.service.js b/packages/server/services/auth/auth.service.js
index 7994910f..c673830a 100644
--- a/packages/server/services/auth/auth.service.js
+++ b/packages/server/services/auth/auth.service.js
@@ -1,4 +1,4 @@
-import { Server } from "linebridge/src/server"
+import { Server } from "linebridge/dist/server"
import DbManager from "@shared-classes/DbManager"
import SharedMiddlewares from "@shared-middlewares"
diff --git a/packages/server/services/auth/package.json b/packages/server/services/auth/package.json
index 64192631..932e2eb2 100644
--- a/packages/server/services/auth/package.json
+++ b/packages/server/services/auth/package.json
@@ -1,10 +1,4 @@
{
"name": "auth",
- "version": "1.0.0",
- "main": "index.js",
- "license": "MIT",
- "proxy":{
- "namespace": "/auth",
- "port": 3020
- }
+ "version": "1.0.0"
}
diff --git a/packages/server/services/auth/routes/auth/post.js b/packages/server/services/auth/routes/auth/post.js
index be750a8e..0d5a123e 100644
--- a/packages/server/services/auth/routes/auth/post.js
+++ b/packages/server/services/auth/routes/auth/post.js
@@ -42,17 +42,18 @@ export default async (req, res) => {
if (mfaSession) {
if (!req.body.mfa_code) {
- await mfaSession.delete()
+ await MFASession.deleteMany({ user_id: user._id })
} else {
if (mfaSession.expires_at < new Date().getTime()) {
- await mfaSession.delete()
+ await MFASession.deleteMany({ user_id: user._id })
throw new OperationError(401, "MFA code expired, login again...")
}
if (mfaSession.code == req.body.mfa_code) {
codeVerified = true
- await mfaSession.delete()
+
+ await MFASession.deleteMany({ user_id: user._id })
} else {
throw new OperationError(401, "Invalid MFA code, try again...")
}
diff --git a/packages/server/services/auth/routes/server-keys/my/get.js b/packages/server/services/auth/routes/server-keys/my/get.js
new file mode 100644
index 00000000..153ce6db
--- /dev/null
+++ b/packages/server/services/auth/routes/server-keys/my/get.js
@@ -0,0 +1,7 @@
+
+export default {
+ middlewares: ["withAuthentication"],
+ fn: async (req, res) => {
+
+ }
+}
\ No newline at end of file
diff --git a/packages/server/services/chats/chats.service.js b/packages/server/services/chats/chats.service.js
index 00762f2f..45fab2e8 100755
--- a/packages/server/services/chats/chats.service.js
+++ b/packages/server/services/chats/chats.service.js
@@ -1,4 +1,4 @@
-import { Server } from "linebridge/src/server"
+import { Server } from "linebridge/dist/server"
import DbManager from "@shared-classes/DbManager"
import RedisClient from "@shared-classes/RedisClient"
diff --git a/packages/server/services/chats/package.json b/packages/server/services/chats/package.json
index 15ef1e24..4e136e1b 100755
--- a/packages/server/services/chats/package.json
+++ b/packages/server/services/chats/package.json
@@ -1,25 +1,4 @@
{
"name": "chats",
- "version": "0.60.2",
- "license": "MIT",
- "dependencies": {
- "@foxify/events": "^2.1.0",
- "axios": "^1.4.0",
- "bcrypt": "5.0.1",
- "comty.js": "^0.58.2",
- "connect-mongo": "^4.6.0",
- "cors": "^2.8.5",
- "dotenv": "^16.0.3",
- "express": "^4.18.2",
- "jsonwebtoken": "8.5.1",
- "linebridge": "0.15.12",
- "luxon": "^3.0.4",
- "minio": "^7.0.32",
- "moment": "2.29.4",
- "moment-timezone": "0.5.37",
- "mongoose": "^6.9.0",
- "morgan": "^1.10.0",
- "redis": "^4.6.6",
- "socket.io": "^4.5.4"
- }
+ "version": "0.60.2"
}
\ No newline at end of file
diff --git a/packages/server/services/chats/routes/chats/[chat_id]/history/get.js b/packages/server/services/chats/routes/chats/[chat_id]/history/get.js
index 0bc02207..ba8d2dda 100644
--- a/packages/server/services/chats/routes/chats/[chat_id]/history/get.js
+++ b/packages/server/services/chats/routes/chats/[chat_id]/history/get.js
@@ -64,7 +64,7 @@ export default {
history = await Promise.all(history)
return {
- total: await ChatMessage.count(query),
+ total: await ChatMessage.countDocuments(query),
offset: offset,
limit: limit,
order: order,
diff --git a/packages/server/services/chats/routes_ws/chat/send/message.js b/packages/server/services/chats/routes_ws/chat/send/message.js
index d7394dab..3dffd912 100644
--- a/packages/server/services/chats/routes_ws/chat/send/message.js
+++ b/packages/server/services/chats/routes_ws/chat/send/message.js
@@ -28,8 +28,6 @@ export default async (socket, payload, engine) => {
const targetSocket = await engine.find.socketByUserId(payload.to_user_id)
- console.log(targetSocket)
-
if (targetSocket) {
await targetSocket.emit("chat:receive:message", wsMessageObj)
}
diff --git a/packages/server/services/ems/ems.service.js b/packages/server/services/ems/ems.service.js
index 4516ad92..b0b47e2b 100644
--- a/packages/server/services/ems/ems.service.js
+++ b/packages/server/services/ems/ems.service.js
@@ -1,4 +1,4 @@
-import { Server } from "linebridge/src/server"
+import { Server } from "linebridge/dist/server"
import nodemailer from "nodemailer"
import DbManager from "@shared-classes/DbManager"
diff --git a/packages/server/services/ems/package.json b/packages/server/services/ems/package.json
index c1beaa73..0f28a259 100644
--- a/packages/server/services/ems/package.json
+++ b/packages/server/services/ems/package.json
@@ -2,12 +2,6 @@
"name": "ems",
"description": "External Messaging Service (SMS, EMAIL, PUSH)",
"version": "0.1.0",
- "main": "index.js",
- "license": "MIT",
- "proxy": {
- "path": "/ems",
- "port": 3007
- },
"dependencies": {
"handlebars": "^4.7.8",
"nodemailer": "^6.9.11",
diff --git a/packages/server/services/files/file.service.js b/packages/server/services/files/file.service.js
index e3e77d89..88f39622 100755
--- a/packages/server/services/files/file.service.js
+++ b/packages/server/services/files/file.service.js
@@ -1,4 +1,4 @@
-import { Server } from "linebridge/src/server"
+import { Server } from "linebridge/dist/server"
import B2 from "backblaze-b2"
diff --git a/packages/server/services/files/package.json b/packages/server/services/files/package.json
index 21fad390..02adaaba 100755
--- a/packages/server/services/files/package.json
+++ b/packages/server/services/files/package.json
@@ -1,31 +1,15 @@
{
"name": "files",
"version": "0.60.2",
- "license": "MIT",
"dependencies": {
- "@foxify/events": "^2.1.0",
- "axios": "^1.4.0",
"backblaze-b2": "^1.7.0",
- "bcrypt": "^5.1.0",
"busboy": "^1.6.0",
- "comty.js": "^0.58.2",
- "connect-mongo": "^4.6.0",
"content-range": "^2.0.2",
- "cors": "^2.8.5",
- "dotenv": "^16.0.3",
- "express": "^4.18.2",
"fluent-ffmpeg": "^2.1.2",
- "jsonwebtoken": "^9.0.0",
- "linebridge": "0.15.12",
- "luxon": "^3.0.4",
"merge-files": "^0.1.2",
"mime-types": "^2.1.35",
"sharp": "0.32.6",
"minio": "^7.0.32",
- "moment": "^2.29.4",
- "moment-timezone": "^0.5.40",
- "mongoose": "^6.9.0",
- "morgan": "^1.10.0",
"normalize-url": "^8.0.0",
"p-map": "4.0.0",
"p-queue": "^7.3.4",
diff --git a/packages/server/services/files/routes/upload/chunk/post.js b/packages/server/services/files/routes/upload/chunk/post.js
index 14469497..ff18b53d 100644
--- a/packages/server/services/files/routes/upload/chunk/post.js
+++ b/packages/server/services/files/routes/upload/chunk/post.js
@@ -5,6 +5,8 @@ import ChunkFileUpload from "@shared-classes/ChunkFileUpload"
import RemoteUpload from "@services/remoteUpload"
+const availableProviders = ["b2", "standard"]
+
export default {
useContext: ["cache", "limits"],
middlewares: [
@@ -34,6 +36,11 @@ export default {
limits.useProvider = req.headers["provider-type"] ?? "b2"
}
+ // check if provider is valid
+ if (!availableProviders.includes(limits.useProvider)) {
+ throw new OperationError(400, "Invalid provider")
+ }
+
let build = await ChunkFileUpload(req, {
tmpDir: tmpPath,
...limits,
diff --git a/packages/server/services/main/controllers/AdminController/endpoints/accounts_statistics.js b/packages/server/services/main/controllers/AdminController/endpoints/accounts_statistics.js
deleted file mode 100755
index 3e910a66..00000000
--- a/packages/server/services/main/controllers/AdminController/endpoints/accounts_statistics.js
+++ /dev/null
@@ -1,58 +0,0 @@
-import { User, Session, Post } from "@db_models"
-
-export default {
- method: "GET",
- route: "/accounts_statistics",
- middlewares: ["withAuthentication", "onlyAdmin"],
- fn: async (req, res) => {
- // get number of users registered,
- const users = await User.count()
-
- // calculate the last 5 days logins from diferent users
- let last5D_logins = await Session.find({
- date: {
- $gte: new Date(Date.now() - 5 * 24 * 60 * 60 * 1000),
- $lte: new Date(),
- }
- })
-
- const last5D_logins_counts = []
-
- // filter from different users
- last5D_logins.forEach((session) => {
- if (!last5D_logins_counts.includes(session.user_id)) {
- last5D_logins_counts.push(session.user_id)
- }
- })
-
- // calculate active users within 1 week (using postings)
- const active_1w_posts_users = await Post.count({
- user_id: {
- $in: last5D_logins_counts
- },
- created_at: {
- $gte: new Date(Date.now() - 7 * 24 * 60 * 60 * 1000),
- $lte: new Date(),
- }
- })
-
- // calculate total posts
- const total_posts = await Post.count()
-
- // calculate total post (1week)
- const total_posts_1w = await Post.count({
- created_at: {
- $gte: new Date(Date.now() - 7 * 24 * 60 * 60 * 1000),
- $lte: new Date(),
- }
- })
-
- return res.json({
- accounts_registered: users,
- last5D_logins: last5D_logins_counts.length,
- active_1w_posts_users: active_1w_posts_users,
- total_posts: total_posts,
- total_posts_1w: total_posts_1w,
- })
- }
-}
\ No newline at end of file
diff --git a/packages/server/services/main/controllers/AdminController/endpoints/delete_featured_wallpaper.js b/packages/server/services/main/controllers/AdminController/endpoints/delete_featured_wallpaper.js
deleted file mode 100755
index 15dfea3b..00000000
--- a/packages/server/services/main/controllers/AdminController/endpoints/delete_featured_wallpaper.js
+++ /dev/null
@@ -1,26 +0,0 @@
-import { FeaturedWallpaper } from "@db_models"
-
-export default {
- method: "DELETE",
- route: "/featured_wallpaper/:id",
- middlewares: ["withAuthentication", "onlyAdmin"],
- fn: async (req, res) => {
- const id = req.params.id
-
- const wallpaper = await FeaturedWallpaper.findById(id)
-
- if (!wallpaper) {
- return res.status(404).json({
- error: "Cannot find wallpaper"
- })
- }
-
- await FeaturedWallpaper.deleteOne({
- _id: id
- })
-
- return res.json({
- done: true
- })
- }
-}
\ No newline at end of file
diff --git a/packages/server/services/main/controllers/AdminController/endpoints/featured_wallpaper.js b/packages/server/services/main/controllers/AdminController/endpoints/featured_wallpaper.js
deleted file mode 100755
index 37658319..00000000
--- a/packages/server/services/main/controllers/AdminController/endpoints/featured_wallpaper.js
+++ /dev/null
@@ -1,39 +0,0 @@
-import { FeaturedWallpaper } from "@db_models"
-import momentTimezone from "moment-timezone"
-
-export default {
- method: "PUT",
- route: "/featured_wallpaper",
- middlewares: ["withAuthentication", "onlyAdmin"],
- fn: async (req, res) => {
- const data = req.body.wallpaper
-
- if (!data) {
- return res.status(400).json({
- error: "Invalid data"
- })
- }
-
- // try to find if data._id exists, else create a new one
- let wallpaper = null
-
- if (data._id) {
- wallpaper = await FeaturedWallpaper.findOne({
- _id: data._id
- })
- } else {
- wallpaper = new FeaturedWallpaper()
- }
-
- const current_timezone = momentTimezone.tz.guess()
-
- wallpaper.active = data.active ?? wallpaper.active ?? true
- wallpaper.date = data.date ?? momentTimezone.tz(Date.now(), current_timezone).format()
- wallpaper.url = data.url ?? wallpaper.url
- wallpaper.author = data.author ?? wallpaper.author
-
- await wallpaper.save()
-
- return res.json(wallpaper)
- }
-}
\ No newline at end of file
diff --git a/packages/server/services/main/controllers/AdminController/endpoints/resetPassword.js b/packages/server/services/main/controllers/AdminController/endpoints/resetPassword.js
deleted file mode 100755
index 7973baab..00000000
--- a/packages/server/services/main/controllers/AdminController/endpoints/resetPassword.js
+++ /dev/null
@@ -1,36 +0,0 @@
-import { User } from "@db_models"
-
-import bcrypt from "bcrypt"
-
-export default {
- method: "POST",
- route: "/update_password/:user_id",
- middlewares: ["withAuthentication", "onlyAdmin"],
- fn: async (req, res) => {
- const { password } = req.body
-
- if (!password) {
- return res.status(400).json({ message: "Missing password" })
- }
-
- const { user_id } = req.params
-
- const user = await User.findById(user_id).select("+password")
-
- if (!user) {
- return res.status(404).json({ message: "User not found" })
- }
-
- // hash the password
- const hash = bcrypt.hashSync(password, parseInt(process.env.BCRYPT_ROUNDS ?? 3))
-
- user.password = hash
-
- await user.save()
-
- return res.status(200).json({
- status: "ok",
- message: "Password updated successfully",
- })
- }
-}
\ No newline at end of file
diff --git a/packages/server/services/main/controllers/AdminController/endpoints/update_user_data.js b/packages/server/services/main/controllers/AdminController/endpoints/update_user_data.js
deleted file mode 100755
index b08f5986..00000000
--- a/packages/server/services/main/controllers/AdminController/endpoints/update_user_data.js
+++ /dev/null
@@ -1,35 +0,0 @@
-import { User } from "@db_models"
-
-export default {
- method: "POST",
- route: "/update_data/:user_id",
- middlewares: ["withAuthentication", "onlyAdmin"],
- fn: async (req, res) => {
- const targetUserId = req.params.user_id
-
- const user = await User.findById(targetUserId).catch((err) => {
- return false
- })
-
- if (!user) {
- return res.status(404).json({ error: "No user founded" })
- }
-
- const updateKeys = Object.keys(req.body.update)
-
- updateKeys.forEach((key) => {
- user[key] = req.body.update[key]
- })
-
- await user.save()
-
- global.engine.ws.io.of("/").emit(`user.update`, {
- ...user.toObject(),
- })
- global.engine.ws.io.of("/").emit(`user.update.${targetUserId}`, {
- ...user.toObject(),
- })
-
- return res.json(user.toObject())
- }
-}
\ No newline at end of file
diff --git a/packages/server/services/main/controllers/AdminController/index.js b/packages/server/services/main/controllers/AdminController/index.js
deleted file mode 100755
index 8ad46ce0..00000000
--- a/packages/server/services/main/controllers/AdminController/index.js
+++ /dev/null
@@ -1,9 +0,0 @@
-import { Controller } from "linebridge/dist/server"
-import generateEndpointsFromDir from "linebridge/dist/server/lib/generateEndpointsFromDir"
-
-export default class AdminController extends Controller {
- static refName = "AdminController"
- static useRoute = "/admin"
-
- httpEndpoints = generateEndpointsFromDir(__dirname + "/endpoints")
-}
\ No newline at end of file
diff --git a/packages/server/services/main/controllers/AutoUpdate/index.js b/packages/server/services/main/controllers/AutoUpdate/index.js
deleted file mode 100755
index bc062989..00000000
--- a/packages/server/services/main/controllers/AutoUpdate/index.js
+++ /dev/null
@@ -1,46 +0,0 @@
-import { Controller } from "linebridge/dist/server"
-
-import { Octokit } from "@octokit/rest"
-
-const octokit = new Octokit({})
-
-const endpoints = {
- post: {
- "/mobile": {
- fn: async (req, res) => {
- if (!process.env.GITHUB_REPO) {
- return res.status(400).json({
- error: "GITHUB_REPO env variable not set"
- })
- }
-
- const lastRelease = await octokit.repos.getLatestRelease({
- owner: process.env.GITHUB_REPO.split("/")[0],
- repo: process.env.GITHUB_REPO.split("/")[1]
- })
-
- const bundle = lastRelease.data.assets.find((asset) => asset.name === "mobile_dist.zip")
- const version = lastRelease.data.tag_name
-
- if (!bundle) {
- return res.status(400).json({
- error: "mobile asset not available",
- version: version,
- })
- }
-
- return res.json({
- url: bundle.browser_download_url,
- version: version,
- })
- }
- }
- }
-}
-
-export default class AutoUpdate extends Controller {
- static refName = "AutoUpdate"
- static useRoute = "/auto-update"
-
- httpEndpoints = endpoints
-}
\ No newline at end of file
diff --git a/packages/server/services/main/controllers/BadgesController/endpoints/deleteBadge.js b/packages/server/services/main/controllers/BadgesController/endpoints/deleteBadge.js
deleted file mode 100755
index ca061bfe..00000000
--- a/packages/server/services/main/controllers/BadgesController/endpoints/deleteBadge.js
+++ /dev/null
@@ -1,21 +0,0 @@
-import { Badge } from "@db_models"
-
-export default {
- method: "DELETE",
- route: "/badge/:badge_id",
- middlewares: ["withAuthentication", "onlyAdmin"],
- fn: async (req, res) => {
- const badge = await Badge.findById(req.params.badge_id).catch((err) => {
- res.status(500).json({ error: err })
- return false
- })
-
- if (!badge) {
- return res.status(404).json({ error: "No badge founded" })
- }
-
- badge.remove()
-
- return res.json(badge)
- }
-}
\ No newline at end of file
diff --git a/packages/server/services/main/controllers/BadgesController/endpoints/getBadges.js b/packages/server/services/main/controllers/BadgesController/endpoints/getBadges.js
deleted file mode 100755
index e5cdeda2..00000000
--- a/packages/server/services/main/controllers/BadgesController/endpoints/getBadges.js
+++ /dev/null
@@ -1,29 +0,0 @@
-import { Schematized } from "@lib"
-import { Badge } from "@db_models"
-
-export default {
- method: "GET",
- route: "/",
- fn: Schematized({
- select: ["_id", "name", "label"],
- }, async (req, res) => {
- let badges = []
-
- if (req.selection._id) {
- badges = await Badge.find({
- _id: { $in: req.selection._id },
- })
-
- badges = badges.map(badge => badge.toObject())
- } else {
- badges = await Badge.find(req.selection).catch((err) => {
- res.status(500).json({ error: err })
- return false
- })
- }
-
- if (badges) {
- return res.json(badges)
- }
- })
-}
\ No newline at end of file
diff --git a/packages/server/services/main/controllers/BadgesController/endpoints/getUserBadges.js b/packages/server/services/main/controllers/BadgesController/endpoints/getUserBadges.js
deleted file mode 100755
index 7b777572..00000000
--- a/packages/server/services/main/controllers/BadgesController/endpoints/getUserBadges.js
+++ /dev/null
@@ -1,21 +0,0 @@
-import { User, Badge } from "@db_models"
-
-export default {
- method: "GET",
- route: "/user/:user_id",
- fn: async (req, res) => {
- const user = await User.findOne({
- _id: req.params.user_id,
- })
-
- if (!user) {
- return res.status(404).json({ error: "User not found" })
- }
-
- const badges = await Badge.find({
- name: { $in: user.badges },
- })
-
- return res.json(badges)
- }
-}
\ No newline at end of file
diff --git a/packages/server/services/main/controllers/BadgesController/endpoints/giveToUser.js b/packages/server/services/main/controllers/BadgesController/endpoints/giveToUser.js
deleted file mode 100755
index 0db01a2b..00000000
--- a/packages/server/services/main/controllers/BadgesController/endpoints/giveToUser.js
+++ /dev/null
@@ -1,41 +0,0 @@
-import { Badge, User } from "@db_models"
-import { Schematized } from "@lib"
-
-export default {
- method: "POST",
- route: "/badge/:badge_id/giveToUser",
- middlewares: ["withAuthentication", "onlyAdmin"],
- fn: Schematized({
- required: ["user_id"],
- select: ["user_id"],
- }, async (req, res) => {
- const badge = await Badge.findById(req.params.badge_id).catch((err) => {
- res.status(500).json({ error: err })
- return false
- })
-
- if (!badge) {
- return res.status(404).json({ error: "No badge founded" })
- }
-
- const user = await User.findById(req.selection.user_id).catch((err) => {
- res.status(500).json({ error: err })
- return false
- })
-
- if (!user) {
- return res.status(404).json({ error: "No user founded" })
- }
-
- // check if user already have this badge
- if (user.badges.includes(badge._id)) {
- return res.status(409).json({ error: "User already have this badge" })
- }
-
- user.badges.push(badge._id.toString())
-
- user.save()
-
- return res.json(user)
- })
-}
\ No newline at end of file
diff --git a/packages/server/services/main/controllers/BadgesController/endpoints/putBadge.js b/packages/server/services/main/controllers/BadgesController/endpoints/putBadge.js
deleted file mode 100755
index 62e38896..00000000
--- a/packages/server/services/main/controllers/BadgesController/endpoints/putBadge.js
+++ /dev/null
@@ -1,27 +0,0 @@
-import { Badge } from "@db_models"
-import { Schematized } from "@lib"
-
-export default {
- method: "PUT",
- route: "/",
- middlewares: ["withAuthentication", "onlyAdmin"],
- fn: Schematized({
- select: ["badge_id", "name", "label", "description", "icon", "color"],
- }, async (req, res) => {
- let badge = await Badge.findById(req.selection.badge_id).catch((err) => null)
-
- if (!badge) {
- badge = new Badge()
- }
-
- badge.name = req.selection.name || badge.name
- badge.label = req.selection.label || badge.label
- badge.description = req.selection.description || badge.description
- badge.icon = req.selection.icon || badge.icon
- badge.color = req.selection.color || badge.color
-
- badge.save()
-
- return res.json(badge)
- })
-}
\ No newline at end of file
diff --git a/packages/server/services/main/controllers/BadgesController/endpoints/removeToUser.js b/packages/server/services/main/controllers/BadgesController/endpoints/removeToUser.js
deleted file mode 100755
index fd9ce0cc..00000000
--- a/packages/server/services/main/controllers/BadgesController/endpoints/removeToUser.js
+++ /dev/null
@@ -1,41 +0,0 @@
-import { Schematized } from "@lib"
-import { Badge, User } from "@db_models"
-
-export default {
- method: "DELETE",
- route: "/badge/:badge_id/removeFromUser",
- middlewares: ["withAuthentication", "onlyAdmin"],
- fn: Schematized({
- required: ["user_id"],
- select: ["user_id"],
- }, async (req, res) => {
- const badge = await Badge.findById(req.params.badge_id).catch((err) => {
- res.status(500).json({ error: err })
- return false
- })
-
- if (!badge) {
- return res.status(404).json({ error: "No badge founded" })
- }
-
- const user = await User.findById(req.selection.user_id).catch((err) => {
- res.status(500).json({ error: err })
- return false
- })
-
- if (!user) {
- return res.status(404).json({ error: "No user founded" })
- }
-
- // check if user already have this badge
- if (!user.badges.includes(badge._id)) {
- return res.status(409).json({ error: "User don't have this badge" })
- }
-
- user.badges = user.badges.filter(b => b !== badge._id.toString())
-
- user.save()
-
- return res.json(user)
- })
-}
\ No newline at end of file
diff --git a/packages/server/services/main/controllers/BadgesController/index.js b/packages/server/services/main/controllers/BadgesController/index.js
deleted file mode 100755
index 3ce58f83..00000000
--- a/packages/server/services/main/controllers/BadgesController/index.js
+++ /dev/null
@@ -1,9 +0,0 @@
-import { Controller } from "linebridge/dist/server"
-import generateEndpointsFromDir from "linebridge/dist/server/lib/generateEndpointsFromDir"
-
-export default class BadgesController extends Controller {
- static refName = "BadgesController"
- static useRoute = "/badge"
-
- httpEndpoints = generateEndpointsFromDir(__dirname + "/endpoints")
-}
\ No newline at end of file
diff --git a/packages/server/services/main/controllers/FeaturedEventsController/index.js b/packages/server/services/main/controllers/FeaturedEventsController/index.js
deleted file mode 100755
index a1d91325..00000000
--- a/packages/server/services/main/controllers/FeaturedEventsController/index.js
+++ /dev/null
@@ -1,63 +0,0 @@
-import { Controller } from "linebridge/dist/server"
-
-import { FeaturedEvent } from "@db_models"
-import createFeaturedEvent from "./services/createFeaturedEvent"
-
-// TODO: Migrate to new linebridge 0.15 endpoint classes instead of this
-
-export default class FeaturedEventsController extends Controller {
- httpEndpoints = {
- get: {
- "/featured_event/:id": async (req, res) => {
- const { id } = req.params
-
- const featuredEvent = await FeaturedEvent.findById(id)
-
- return res.json(featuredEvent)
- },
- "/featured_events": async (req, res) => {
- let query = {
- expired: false
- }
-
- if (req.query.includeExpired) {
- delete query.expired
- }
-
- const featuredEvents = await FeaturedEvent.find(query)
-
- return res.json(featuredEvents)
- }
- },
- post: {
- "/featured_event": {
- middlewares: ["withAuthentication", "onlyAdmin"],
- fn: async (req, res) => {
- const result = await createFeaturedEvent(req.body).catch((err) => {
- res.status(500).json({
- error: err.message
- })
-
- return null
- })
-
- if (result) {
- return res.json(result)
- }
- }
- }
- },
- delete: {
- "/featured_event/:id": {
- middlewares: ["withAuthentication", "onlyAdmin"],
- fn: async (req, res) => {
- const { id } = req.params
-
- const featuredEvent = await FeaturedEvent.findByIdAndDelete(id)
-
- return res.json(featuredEvent)
- }
- }
- },
- }
-}
\ No newline at end of file
diff --git a/packages/server/services/main/controllers/FeaturedEventsController/services/createFeaturedEvent.js b/packages/server/services/main/controllers/FeaturedEventsController/services/createFeaturedEvent.js
deleted file mode 100755
index 97c25de7..00000000
--- a/packages/server/services/main/controllers/FeaturedEventsController/services/createFeaturedEvent.js
+++ /dev/null
@@ -1,27 +0,0 @@
-import { FeaturedEvent } from "@db_models"
-
-export default async (payload) => {
- const {
- name,
- category,
- description,
- dates,
- location,
- announcement,
- customHeader,
- } = payload
-
- const featuredEvent = new FeaturedEvent({
- name,
- category,
- description,
- dates,
- location,
- announcement,
- customHeader,
- })
-
- await featuredEvent.save()
-
- return featuredEvent
-}
\ No newline at end of file
diff --git a/packages/server/services/main/controllers/NFCController/endpoints/getExecution.js b/packages/server/services/main/controllers/NFCController/endpoints/getExecution.js
deleted file mode 100755
index 6d63dc4a..00000000
--- a/packages/server/services/main/controllers/NFCController/endpoints/getExecution.js
+++ /dev/null
@@ -1,11 +0,0 @@
-export default {
- method: "GET",
- route: "/execution/:user_id",
- fn: async (req, res) => {
- let execution = {
-
- }
-
- return res.json(execution)
- }
-}
\ No newline at end of file
diff --git a/packages/server/services/main/controllers/NFCController/index.js b/packages/server/services/main/controllers/NFCController/index.js
deleted file mode 100755
index 2691c570..00000000
--- a/packages/server/services/main/controllers/NFCController/index.js
+++ /dev/null
@@ -1,9 +0,0 @@
-import { Controller } from "linebridge/dist/server"
-import generateEndpointsFromDir from "linebridge/dist/server/lib/generateEndpointsFromDir"
-
-export default class NFCController extends Controller {
- static refName = "NFCController"
- static useRoute = "/nfc"
-
- httpEndpoints = generateEndpointsFromDir(__dirname + "/endpoints")
-}
\ No newline at end of file
diff --git a/packages/server/services/main/controllers/PublicController/endpoints/featuredWallpapers.js b/packages/server/services/main/controllers/PublicController/endpoints/featuredWallpapers.js
deleted file mode 100755
index 2b92f6f9..00000000
--- a/packages/server/services/main/controllers/PublicController/endpoints/featuredWallpapers.js
+++ /dev/null
@@ -1,28 +0,0 @@
-import { FeaturedWallpaper } from "@db_models"
-
-export default {
- method: "GET",
- route: "/featured_wallpapers",
- fn: async (req, res) => {
- const { all } = req.query
-
- const query = {
- active: true
- }
-
- if (all) {
- delete query.active
- }
-
- const featuredWallpapers = await FeaturedWallpaper.find(query)
- .sort({ date: -1 })
- .limit(all ? undefined : 10)
- .catch(err => {
- return res.status(500).json({
- error: err.message
- }).end()
- })
-
- return res.json(featuredWallpapers)
- }
-}
\ No newline at end of file
diff --git a/packages/server/services/main/controllers/PublicController/endpoints/getReleasesNotes.js b/packages/server/services/main/controllers/PublicController/endpoints/getReleasesNotes.js
deleted file mode 100755
index f3b61341..00000000
--- a/packages/server/services/main/controllers/PublicController/endpoints/getReleasesNotes.js
+++ /dev/null
@@ -1,49 +0,0 @@
-import { Octokit } from "@octokit/rest"
-import axios from "axios"
-
-const octokit = new Octokit({})
-
-export default {
- method: "GET",
- route: "/release-notes",
- fn: async (req, res) => {
- if (!process.env.GITHUB_REPO) {
- return res.status(400).json({
- error: "GITHUB_REPO env variable not set"
- })
- }
-
- const releasesNotes = []
-
- // fetch the 3 latest releases
- const releases = await octokit.repos.listReleases({
- owner: process.env.GITHUB_REPO.split("/")[0],
- repo: process.env.GITHUB_REPO.split("/")[1],
- per_page: 3
- })
-
- for await (const release of releases.data) {
- let changelogData = release.body
-
- const bundle = release.assets.find((asset) => asset.name === "changelog.md")
-
- if (bundle) {
- const response = await axios.get(bundle.browser_download_url)
- .catch(() => null)
-
- if (response) {
- changelogData = response.data
- }
- }
-
- releasesNotes.push({
- version: release.tag_name,
- date: release.published_at,
- body: changelogData,
- isMd: bundle !== undefined
- })
- }
-
- return res.json(releasesNotes)
- }
-}
\ No newline at end of file
diff --git a/packages/server/services/main/controllers/PublicController/endpoints/globalServerLimits.js b/packages/server/services/main/controllers/PublicController/endpoints/globalServerLimits.js
deleted file mode 100755
index f0701535..00000000
--- a/packages/server/services/main/controllers/PublicController/endpoints/globalServerLimits.js
+++ /dev/null
@@ -1,27 +0,0 @@
-import { ServerLimit } from "@db_models"
-
-export default {
- method: "GET",
- route: "/global_server_limits/:limitkey",
- fn: async (req, res) => {
- const { limitkey } = req.params
-
- const serverLimit = await ServerLimit.findOne({
- key: limitkey,
- active: true,
- })
- .catch(err => {
- return res.status(500).json({
- error: err.message
- })
- })
-
- if (!serverLimit) {
- return res.status(404).json({
- error: "Server limit not found or inactive"
- })
- }
-
- return res.json(serverLimit)
- }
-}
\ No newline at end of file
diff --git a/packages/server/services/main/controllers/PublicController/endpoints/ping.js b/packages/server/services/main/controllers/PublicController/endpoints/ping.js
deleted file mode 100755
index 324631bf..00000000
--- a/packages/server/services/main/controllers/PublicController/endpoints/ping.js
+++ /dev/null
@@ -1,7 +0,0 @@
-export default {
- route: "/ping",
- method: "GET",
- fn: async (req, res) => {
- return res.send("pong")
- }
-}
\ No newline at end of file
diff --git a/packages/server/services/main/controllers/PublicController/endpoints/postingPolicy.js b/packages/server/services/main/controllers/PublicController/endpoints/postingPolicy.js
deleted file mode 100755
index 74169649..00000000
--- a/packages/server/services/main/controllers/PublicController/endpoints/postingPolicy.js
+++ /dev/null
@@ -1,9 +0,0 @@
-export default {
- method: "GET",
- route: "/posting_policy",
- middlewares: ["withOptionalAuthentication"],
- fn: async (req, res) => {
- // TODO: Use `PermissionsAPI` to get the user's permissions and return the correct policy, by now it will return the default policy
- return res.json(global.DEFAULT_POSTING_POLICY)
- }
-}
\ No newline at end of file
diff --git a/packages/server/services/main/controllers/PublicController/endpoints/serverHealth.js b/packages/server/services/main/controllers/PublicController/endpoints/serverHealth.js
deleted file mode 100755
index caa02e90..00000000
--- a/packages/server/services/main/controllers/PublicController/endpoints/serverHealth.js
+++ /dev/null
@@ -1,29 +0,0 @@
-const os = require("os")
-
-function getUsage() {
- let usage = process.cpuUsage()
-
- usage.time = process.uptime() * 1000
- usage.percent = (usage.system + usage.user) / (usage.time * 10)
-
- return usage
-}
-
-export default {
- method: "GET",
- route: "/server/health",
- fn: async (req, res) => {
- const cpus = os.cpus()
-
- // get process info, memory usage, etc
- const processInfo = {
- memoryUsage: process.memoryUsage(),
- cpuUsage: getUsage(),
- uptime: process.uptime(),
- memoryUsage: process.memoryUsage(),
- cpus: cpus,
- }
-
- return res.json(processInfo)
- }
-}
\ No newline at end of file
diff --git a/packages/server/services/main/controllers/PublicController/incidentPrediction.js b/packages/server/services/main/controllers/PublicController/incidentPrediction.js
deleted file mode 100755
index 3acdff5a..00000000
--- a/packages/server/services/main/controllers/PublicController/incidentPrediction.js
+++ /dev/null
@@ -1,27 +0,0 @@
-// import { Schematized } from "../../../lib"
-// import IndecentPrediction from "../../../utils/indecent-prediction"
-
-// export default {
-// method: "GET",
-// route: "/indecent_prediction",
-// fn: Schematized({
-// select: ["url"],
-// required: ["url"],
-// }, async (req, res) => {
-// const { url } = req.selection
-
-// const predictions = await IndecentPrediction({
-// url,
-// }).catch((err) => {
-// res.status(500).json({
-// error: err.message,
-// })
-
-// return null
-// })
-
-// if (predictions) {
-// return res.json(predictions)
-// }
-// })
-// }
\ No newline at end of file
diff --git a/packages/server/services/main/controllers/PublicController/index.js b/packages/server/services/main/controllers/PublicController/index.js
deleted file mode 100755
index 3ff1e414..00000000
--- a/packages/server/services/main/controllers/PublicController/index.js
+++ /dev/null
@@ -1,8 +0,0 @@
-import { Controller } from "linebridge/src/server"
-import generateEndpointsFromDir from "linebridge/src/server/lib/generateEndpointsFromDir"
-
-export default class PublicController extends Controller {
- static refName = "PublicController"
-
- httpEndpoints = generateEndpointsFromDir(__dirname + "/endpoints")
-}
\ No newline at end of file
diff --git a/packages/server/services/main/controllers/SearchController/endpoints/getQuickSearch.js b/packages/server/services/main/controllers/SearchController/endpoints/getQuickSearch.js
deleted file mode 100755
index 29bf83cd..00000000
--- a/packages/server/services/main/controllers/SearchController/endpoints/getQuickSearch.js
+++ /dev/null
@@ -1,20 +0,0 @@
-import getMutuals from "@services/getMutuals"
-
-export default {
- method: "GET",
- route: "/quick",
- middlewares: ["withAuthentication"],
- fn: async (req, res) => {
- let mutuals = await getMutuals({
- from_user_id: req.user._id.toString(),
- }).catch((error) => {
- console.error(error)
-
- return []
- })
-
- return res.json({
- friends: mutuals,
- })
- }
-}
\ No newline at end of file
diff --git a/packages/server/services/main/controllers/SearchController/endpoints/getSearch.js b/packages/server/services/main/controllers/SearchController/endpoints/getSearch.js
deleted file mode 100755
index 933e54d8..00000000
--- a/packages/server/services/main/controllers/SearchController/endpoints/getSearch.js
+++ /dev/null
@@ -1,86 +0,0 @@
-import { User, Playlist, Track } from "@db_models"
-import pmap from "p-map"
-
-export default {
- method: "GET",
- route: "/",
- middlewares: ["withOptionalAuthentication"],
- fn: async (req, res) => {
- const { keywords = "", params = {} } = req.query
-
- let suggestions = {}
-
- const searchers = [
- {
- id: "users",
- model: User,
- query: {
- $or: [
- { username: { $regex: keywords, $options: "i" } },
- { fullName: { $regex: keywords, $options: "i" } },
- ]
- },
- limit: params.limit_per_section ?? 5,
- select: "username fullName avatar verified",
- },
- {
- id: "playlists",
- model: Playlist,
- query: {
- $or: [
- { title: { $regex: keywords, $options: "i" } },
- ]
- },
- limit: params.limit_per_section ?? 5,
- },
- {
- id: "tracks",
- model: Track,
- query: {
- $or: [
- { title: { $regex: keywords, $options: "i" } },
- { author: { $regex: keywords, $options: "i" } },
- { album: { $regex: keywords, $options: "i" } },
- ]
- },
- limit: params.limit_per_section ?? 5,
- }
- ]
-
- let selectedSearchers = []
-
- if (!Array.isArray(params.select)) {
- selectedSearchers = searchers
- } else {
- const findedSearchers = []
-
- for (const searcher of searchers) {
- if (params.select.includes(searcher.id)) {
- findedSearchers.push(searcher)
- }
- }
-
- selectedSearchers = findedSearchers
- }
-
- await pmap(
- selectedSearchers,
- async (searcher) => {
- let results = await searcher.model.find(searcher.query)
- .limit(searcher.limit ?? 5)
- .select(searcher.select ?? undefined)
-
- if (results.length > 0) {
- suggestions[searcher.id] = results
- }
-
- return
- },
- {
- concurrency: 3
- }
- )
-
- return res.json(suggestions)
- }
-}
\ No newline at end of file
diff --git a/packages/server/services/main/controllers/SearchController/index.js b/packages/server/services/main/controllers/SearchController/index.js
deleted file mode 100755
index c2d10021..00000000
--- a/packages/server/services/main/controllers/SearchController/index.js
+++ /dev/null
@@ -1,9 +0,0 @@
-import { Controller } from "linebridge/dist/server"
-import generateEndpointsFromDir from "linebridge/dist/server/lib/generateEndpointsFromDir"
-
-export default class SearchController extends Controller {
- static refName = "SearchController"
- static useRoute = "/search"
-
- httpEndpoints = generateEndpointsFromDir(__dirname + "/endpoints")
-}
\ No newline at end of file
diff --git a/packages/server/services/main/controllers/StatusController/endpoints/getConnectedFollowedUsers.js b/packages/server/services/main/controllers/StatusController/endpoints/getConnectedFollowedUsers.js
deleted file mode 100755
index 335ad726..00000000
--- a/packages/server/services/main/controllers/StatusController/endpoints/getConnectedFollowedUsers.js
+++ /dev/null
@@ -1,16 +0,0 @@
-import { Endpoint } from "linebridge/dist/server"
-import getConnectedUsersFollowing from "../services/getConnectedUsersFollowing"
-
-export default class GetConnectedFollowedUsers extends Endpoint {
- static method = "GET"
- static route = "/connected/following"
- static middlewares = ["withAuthentication"]
-
- async fn(req, res) {
- const users = await getConnectedUsersFollowing({
- from_user_id: req.user._id.toString(),
- })
-
- return res.json(users)
- }
-}
\ No newline at end of file
diff --git a/packages/server/services/main/controllers/StatusController/index.js b/packages/server/services/main/controllers/StatusController/index.js
deleted file mode 100755
index 6532ba3b..00000000
--- a/packages/server/services/main/controllers/StatusController/index.js
+++ /dev/null
@@ -1,9 +0,0 @@
-import { Controller } from "linebridge/dist/server"
-import generateEndpointsFromDir from "linebridge/dist/server/lib/generateEndpointsFromDir"
-
-export default class StatusController extends Controller {
- static refName = "StatusController"
- static useRoute = "/status"
-
- httpEndpoints = generateEndpointsFromDir(__dirname + "/endpoints")
-}
\ No newline at end of file
diff --git a/packages/server/services/main/controllers/StatusController/services/getConnectedUsersFollowing.js b/packages/server/services/main/controllers/StatusController/services/getConnectedUsersFollowing.js
deleted file mode 100755
index b78d51ae..00000000
--- a/packages/server/services/main/controllers/StatusController/services/getConnectedUsersFollowing.js
+++ /dev/null
@@ -1,28 +0,0 @@
-import { UserFollow } from "@db_models"
-
-export default async (payload = {}) => {
- const { from_user_id, limit = 10, offset = 0 } = payload
-
- // TODO: Sort by latest history interaction
-
- // get all the users that are following
- let followingUsersIds = await UserFollow.find({
- user_id: from_user_id,
- })
- // .skip(offset)
- // .limit(limit)
-
- followingUsersIds = followingUsersIds.map((follow) => {
- return follow.to
- })
-
- const searchResult = await global.engine.ws.find.manyById(followingUsersIds)
-
- // TODO: Calculate last session duration or last activity at
- return searchResult.map((user) => {
- return {
- _id: user.user_id,
- username: user.username,
- }
- })
-}
\ No newline at end of file
diff --git a/packages/server/services/main/controllers/index.js b/packages/server/services/main/controllers/index.js
deleted file mode 100755
index 48b289cb..00000000
--- a/packages/server/services/main/controllers/index.js
+++ /dev/null
@@ -1,25 +0,0 @@
-export { default as UserController } from "./UserController"
-export { default as SessionController } from "./SessionController"
-
-export { default as StatusController } from "./StatusController"
-export { default as FollowController } from "./FollowController"
-
-export { default as PostsController } from "./PostsController"
-export { default as CommentsController } from "./CommentsController"
-export { default as FeedController } from "./FeedController" // Needs to migrate to lb 0.15
-
-export { default as StreamingController } from "./StreamingController"
-
-export { default as BadgesController } from "./BadgesController"
-export { default as FeaturedEventsController } from "./FeaturedEventsController" // Needs to migrate to lb 0.15
-
-export { default as RolesController } from "./RolesController" // Needs to migrate to lb 0.15
-export { default as SearchController } from "./SearchController" // Needs to migrate to lb 0.15
-
-export { default as ModerationController } from "./ModerationController"
-
-export { default as AdminController } from "./AdminController"
-
-export { default as AutoUpdateController } from "./AutoUpdate"
-
-export { default as NFCController } from "./NFCController"
\ No newline at end of file
diff --git a/packages/server/services/main/fixments/additions_to_attachments.js b/packages/server/services/main/fixments/additions_to_attachments.js
deleted file mode 100755
index 58634d7b..00000000
--- a/packages/server/services/main/fixments/additions_to_attachments.js
+++ /dev/null
@@ -1,26 +0,0 @@
-import { Post } from "@db_models"
-import DBManager from "../classes/DbManager"
-
-async function main() {
- const dbManager = new DBManager()
- await dbManager.connect()
-
- const posts = await Post.find({}).catch(() => false)
-
- for await (let post of posts) {
- let postData = post.toObject()
-
- if (postData["additions"]) {
- // transform additions to attachments
- postData["attachments"] = postData["additions"]
- }
-
- post.attachments = postData["attachments"]
-
- await post.save()
- }
-
- console.log("Done!")
-}
-
-main()
\ No newline at end of file
diff --git a/packages/server/services/main/fixments/migrate_posts_likes.js b/packages/server/services/main/fixments/migrate_posts_likes.js
deleted file mode 100755
index 81d3b0bf..00000000
--- a/packages/server/services/main/fixments/migrate_posts_likes.js
+++ /dev/null
@@ -1,96 +0,0 @@
-require("dotenv").config()
-
-import fs from "fs"
-import path from "path"
-
-import { Post, PostLike } from "@db_models"
-import { performance } from "perf_hooks"
-import DBManager from "../classes/DbManager"
-
-const logBuffer = []
-
-function log(...args) {
- console.log(...args)
-
- logBuffer.push(`[${new Date().toISOString()}] | ${args.join(" ")}`)
-}
-
-process.on("unhandledRejection", (reason, promise) => {
- log("🆘 Unhandled Rejection at:", promise, "reason:", reason)
-
- writeLog()
-
- process.exit(1)
-})
-
-process.on("uncaughtException", (err) => {
- log("🆘 Uncaught Exception at:", err)
-
- writeLog()
-
- process.exit(1)
-})
-
-function writeLog() {
- fs.writeFileSync(path.resolve(process.cwd(), `migrate_posts_likes.${new Date().getTime()}.log`), logBuffer.join("\n"))
-}
-
-async function main() {
- const dbManager = new DBManager()
- await dbManager.connect()
-
- log(`Starting migration...`)
-
- const posts = await Post.find({}).catch(() => false)
-
- log(`✅ Found ${posts.length} posts`)
-
- for await (let post of posts) {
- let postData = post
-
- log(`➡️ Migrating post likes of [${post._id}]...`)
-
- const postMigrationStartTime = performance.now()
-
- if (postData["likes"]) {
- // create a PostLike for each like
- for await (let like of postData["likes"]) {
- try {
- // check if the PostLike already exists
- let likeObj = await PostLike.findOne({
- post_id: post._id,
- user_id: like,
- }).catch(() => false)
-
- if (likeObj) {
- log(`🔗 PostLike for [${like}] already exists, skipping...`)
- continue
- }
-
- log(`🔗 Creating PostLike for [${like}]...`)
-
- likeObj = new PostLike({
- post_id: post._id,
- user_id: like,
- })
-
- await likeObj.save()
-
- log(`🔗✅ Created PostLike for [${like}]`)
- } catch (error) {
- log(`🔗❌ Error while creating PostLike for [${like}]:`, error)
- }
- }
- }
-
- const postMigrationEndTime = performance.now()
-
- log(`⏱️ Post likes migration of [${post._id}] took ${postMigrationEndTime - postMigrationStartTime}ms`)
- }
-
- log(`✅ Migrated ${posts.length} posts`)
-
- writeLog()
-}
-
-main()
\ No newline at end of file
diff --git a/packages/server/services/main/fixments/move_playlist_to_release.js b/packages/server/services/main/fixments/move_playlist_to_release.js
deleted file mode 100755
index db0a7cae..00000000
--- a/packages/server/services/main/fixments/move_playlist_to_release.js
+++ /dev/null
@@ -1,47 +0,0 @@
-import { Release, Playlist } from "@db_models"
-import DBManager from "@shared-classes/DbManager"
-
-async function main() {
- console.log(`Running fixment move_playlist_to_release...`)
-
- const dbManager = new DBManager()
- await dbManager.initialize()
-
- const playlists = await Playlist.find({}).catch(() => false)
-
- console.log(`Found ${playlists.length} playlists`)
-
- for await (let playlist of playlists) {
- console.log(`Moving playlist ${playlist._id} to release...`)
-
- let data = playlist.toObject()
-
- let release = await Release.findOne(data).catch((err) => {
- return false
- })
-
- if (release) {
- console.log(`Release for playlist ${playlist._id} already exists, skipping...`)
- continue
- }
-
- release = new Release({
- user_id: data.user_id,
- title: data.title,
- type: "album",
- list: data.list,
- cover: data.cover,
- created_at: data.created_at ?? new Date(),
- publisher: data.publisher,
- public: data.public
- })
-
- console.log(`Playlist ${playlist._id} done`)
-
- await release.save()
- }
-
- console.log("Done!")
-}
-
-main()
\ No newline at end of file
diff --git a/packages/server/services/main/lib/checkUserAdmin/index.js b/packages/server/services/main/lib/checkUserAdmin/index.js
deleted file mode 100755
index 3c999e4e..00000000
--- a/packages/server/services/main/lib/checkUserAdmin/index.js
+++ /dev/null
@@ -1,19 +0,0 @@
-import { User } from "@db_models"
-
-export default async (user_id) => {
- if (!user_id) {
- throw new Error("Missing user id")
- }
-
- const user = await User.findById(user_id)
-
- if (!user) {
- throw new Error("User not found")
- }
-
- if (!user.roles.includes("admin")) {
- return false
- }
-
- return true
-}
\ No newline at end of file
diff --git a/packages/server/services/main/lib/chunkedUpload/index.js b/packages/server/services/main/lib/chunkedUpload/index.js
deleted file mode 100755
index 976a3527..00000000
--- a/packages/server/services/main/lib/chunkedUpload/index.js
+++ /dev/null
@@ -1,232 +0,0 @@
-import fs from "fs"
-import path from "path"
-import mime from "mime-types"
-import Busboy from "busboy"
-import crypto from "crypto"
-import { fsMerge } from "split-chunk-merge"
-
-export default class ChunkedUpload {
- constructor(options = {}) {
- this.options = options
-
- this.outputPath = options.outputPath
- this.tmpPath = options.tmpPath ?? "/tmp"
-
- this.maxFileSize = options.maxFileSize ?? 95
- this.acceptedMimeTypes = options.acceptedMimeTypes ?? [
- "image/*",
- "video/*",
- "audio/*",
- ]
-
- this.strictHashCheck = options.strictHashCheck ?? false
-
- if (!this.outputPath) {
- throw new Error("Missing outputPath")
- }
- }
-
- _isLastPart = (contentRange) => {
- return contentRange.size === contentRange.end + 1
- }
-
- _makeSureDirExists = dirName => {
- if (!fs.existsSync(dirName)) {
- fs.mkdirSync(dirName, { recursive: true })
- }
- }
-
- _buildOriginalFile = async (fileHash, filename) => {
- const chunkPartsPath = path.join(this.tmpPath, fileHash)
- const mergedFilePath = path.join(this.outputPath, filename)
-
- let partsFilenames = fs.readdirSync(chunkPartsPath)
-
- // sort the parts
- partsFilenames = partsFilenames.sort((a, b) => {
- const aNumber = Number(a)
- const bNumber = Number(b)
-
- if (aNumber < bNumber) {
- return -1
- }
-
- if (aNumber > bNumber) {
- return 1
- }
-
- return 0
- })
-
- partsFilenames = partsFilenames.map((partFilename) => {
- return path.join(chunkPartsPath, partFilename)
- })
-
- // merge the parts
- await fsMerge(partsFilenames, mergedFilePath)
-
- // check hash
- if (this.strictHashCheck) {
- const mergedFileHash = await this._getFileHash(mergedFilePath)
-
- if (mergedFileHash !== fileHash) {
- throw new Error("File hash mismatch")
- }
- }
-
- //fs.rmdirSync(chunkPartsPath, { recursive: true })
-
- return mergedFilePath
- }
-
- _getFileHash = async (filePath) => {
- const buffer = await fs.promises.readFile(filePath)
-
- const hash = await crypto.createHash("sha256")
- .update(buffer)
- .digest()
-
- return hash.toString("hex")
- }
-
- makeMiddleware = () => {
- return (req, res, next) => {
- const busboy = Busboy({ headers: req.headers })
-
- busboy.on("file", async (fieldName, file, info) => {
- try {
- const fileHash = req.headers["file-hash"]
- const chunkNumber = req.chunkNumber = req.headers["file-chunk-number"]
- const totalChunks = req.headers["file-total-chunks"]
- const fileSize = req.headers["file-size"]
-
- if (!fileHash) {
- return res.status(400).json({
- error: "Missing header [file-hash]",
- })
- }
-
- if (!chunkNumber) {
- return res.status(400).json({
- error: "Missing header [file-chunk-number]",
- })
- }
-
- if (!totalChunks) {
- return res.status(400).json({
- error: "Missing header [file-total-chunks]",
- })
- }
-
- if (!fileSize) {
- return res.status(400).json({
- error: "Missing header [file-size]",
- })
- }
-
- // check if file size is allowed
- if (fileSize > this.maxFileSize) {
- if (typeof this.options.onExceedMaxFileSize === "function") {
- const result = await this.options.onExceedMaxFileSize({
- fileHash,
- chunkNumber,
- totalChunks,
- fileSize,
- headers: req.headers,
- user: req.user,
- })
-
- if (!result) {
- return res.status(413).json({
- error: "File size is too big",
- })
- }
- } else {
- return res.status(413).json({
- error: "File size is too big",
- })
- }
- }
-
- // check if allowedMimeTypes is an array and if it contains the file's mimetype
- if (this.acceptedMimeTypes && Array.isArray(this.acceptedMimeTypes)) {
- const regex = new RegExp(this.acceptedMimeTypes.join("|").replace(/\*/g, "[a-z]+").replace(/!/g, "^"), "i")
-
- if (!regex.test(info.mimeType)) {
- return res.status(400).json({
- error: "File type is not allowed",
- mimeType: info.mimeType,
- })
- }
- }
-
- const filePath = path.join(this.tmpPath, fileHash)
- const chunkPath = path.join(filePath, chunkNumber)
-
- this._makeSureDirExists(filePath)
-
- const writeStream = fs.createWriteStream(chunkPath, { flags: "a" })
-
- file.pipe(writeStream)
-
- file.on("end", async () => {
- if (Number(chunkNumber) === totalChunks - 1) {
- try {
- // build final filename
- const realMimeType = mime.lookup(info.filename)
- const finalFilenameExtension = mime.extension(realMimeType)
- const finalFilename = `${fileHash}.${finalFilenameExtension}`
-
- const buildResult = await this._buildOriginalFile(
- fileHash,
- finalFilename,
- )
- .catch((err) => {
- res.status(500).json({
- error: "Failed to build final file",
- })
-
- return false
- })
-
- if (buildResult) {
- req.isLastPart = true
- req.fileResult = {
- fileHash,
- filepath: buildResult,
- filename: finalFilename,
- mimetype: realMimeType,
- size: fileSize,
- }
-
- global.cacheService.appendToDeletion(buildResult)
-
- next()
- }
- } catch (error) {
- return res.status(500).json({
- error: "Failed to build final file",
- })
- }
- } else {
- req.isLastPart = false
-
- return res.status(200).json({
- message: "Chunk uploaded",
- chunkNumber,
- })
- }
- })
- } catch (error) {
- console.log("error:", error)
-
- return res.status(500).json({
- error: "Failed to upload file",
- })
- }
- })
-
- req.pipe(busboy)
- }
- }
-}
\ No newline at end of file
diff --git a/packages/server/services/main/lib/index.js b/packages/server/services/main/lib/index.js
deleted file mode 100755
index 8a71e94d..00000000
--- a/packages/server/services/main/lib/index.js
+++ /dev/null
@@ -1,3 +0,0 @@
-export { default as Schematized } from "./schematized"
-
-export * as Token from "./token"
\ No newline at end of file
diff --git a/packages/server/services/main/lib/schematized/index.js b/packages/server/services/main/lib/schematized/index.js
deleted file mode 100755
index 87ec0030..00000000
--- a/packages/server/services/main/lib/schematized/index.js
+++ /dev/null
@@ -1,66 +0,0 @@
-export default (schema = {}, fn) => {
- return async (req, res, next) => {
- if (typeof req.body === "undefined") {
- req.body = {}
- }
- if (typeof req.query === "undefined") {
- req.query = {}
- }
-
- if (typeof req.selection !== "object") {
- req.selection = {}
- }
-
- if (schema.required) {
- if (!Array.isArray(schema.required)) {
- console.warn("[INVALID SCHEMA] schema.required is defined but is not an array")
- return
- }
-
- const missingKeys = []
- const requiredKeys = Array.isArray(schema.required) ? schema.required : []
-
- for (let key of requiredKeys) {
- const value = req.body[key] || req.query[key]
-
- if (!value || typeof value === "undefined") {
- missingKeys.push(key)
- break
- }
-
- req.selection[key] = value
- }
-
- if (missingKeys.length > 0) {
- return res.status(400).json({
- error: `Missing required keys > ${missingKeys}`,
- missingKeys: missingKeys
- })
- }
- }
-
- if (schema.select) {
- if (!Array.isArray(schema.select)) {
- console.warn("[INVALID SCHEMA] schema.select is defined but is not an array")
- return
- }
-
- // assign objects along request body and query.
- for await (let key of schema.select) {
- if (req.body && typeof req.body[key] !== "undefined") {
- req.selection[key] = req.body[key]
- continue
- }
-
- if (req.query && typeof req.query[key] !== "undefined") {
- req.selection[key] = req.query[key]
- continue
- }
- }
- }
-
- if (typeof fn === "function") {
- return await fn(req, res, next)
- }
- }
-}
\ No newline at end of file
diff --git a/packages/server/services/main/lib/secureEntry/index.js b/packages/server/services/main/lib/secureEntry/index.js
deleted file mode 100755
index e7591da0..00000000
--- a/packages/server/services/main/lib/secureEntry/index.js
+++ /dev/null
@@ -1,133 +0,0 @@
-import crypto from "crypto"
-
-export default class SecureEntry {
- constructor(model, params = {}) {
- this.params = params
-
- if (!model) {
- throw new Error("Missing model")
- }
-
- this.model = model
- }
-
- static get encrytionAlgorithm() {
- return "aes-256-cbc"
- }
-
- async set(key, value, {
- keyName = "key",
- valueName = "value",
- }) {
- if (!keyName) {
- throw new Error("Missing keyName")
- }
-
- if (!valueName) {
- throw new Error("Missing valueName")
- }
-
- if (!key) {
- throw new Error("Missing key")
- }
-
- if (!value) {
- throw new Error("Missing value")
- }
-
- let entry = await this.model.findOne({
- [keyName]: key,
- [valueName]: value,
- }).catch(() => null)
-
- const encryptionKey = Buffer.from(process.env.SYNC_ENCRIPT_SECRET, "hex")
- const iv = crypto.randomBytes(16)
-
- const cipher = crypto.createCipheriv(SecureEntry.encrytionAlgorithm, encryptionKey, iv)
-
- let encryptedData
-
- try {
- encryptedData = cipher.update(value)
- }
- catch (error) {
- console.error(error)
- }
-
- encryptedData = Buffer.concat([encryptedData, cipher.final()])
-
- value = iv.toString("hex") + ":" + encryptedData.toString("hex")
-
- if (entry) {
- entry[valueName] = value
-
- await entry.save()
-
- return entry
- }
-
- entry = new this.model({
- [keyName]: key,
- [valueName]: value,
- })
-
- await entry.save()
-
- return entry
- }
-
- async get(key, value, {
- keyName = "key",
- valueName = "value",
- }) {
- if (!keyName) {
- throw new Error("Missing keyName")
- }
- if (!key) {
- throw new Error("Missing key")
- }
-
- const searchQuery = {
- [keyName]: key,
- }
-
- if (value) {
- searchQuery[valueName] = value
- }
-
- const entry = await this.model.findOne(searchQuery).catch(() => null)
-
- if (!entry || !entry[valueName]) {
- return null
- }
-
- const encryptionKey = Buffer.from(process.env.SYNC_ENCRIPT_SECRET, "hex")
-
- const iv = Buffer.from(entry[valueName].split(":")[0], "hex")
- const encryptedText = Buffer.from(entry[valueName].split(":")[1], "hex")
-
- const decipher = crypto.createDecipheriv(SecureEntry.encrytionAlgorithm, encryptionKey, iv)
-
- let decrypted = decipher.update(encryptedText)
-
- decrypted = Buffer.concat([decrypted, decipher.final()])
-
- return decrypted.toString()
- }
-
- async deleteByID(_id) {
- if (!_id) {
- throw new Error("Missing _id")
- }
-
- const entry = await this.model.findById(_id).catch(() => null)
-
- if (!entry) {
- return null
- }
-
- await entry.delete()
-
- return entry
- }
-}
\ No newline at end of file
diff --git a/packages/server/services/main/lib/token/index.js b/packages/server/services/main/lib/token/index.js
deleted file mode 100755
index 0cfe9b51..00000000
--- a/packages/server/services/main/lib/token/index.js
+++ /dev/null
@@ -1,223 +0,0 @@
-import jwt from "jsonwebtoken"
-import { Session, RegenerationToken } from "@db_models"
-
-export default class Token {
- static async createNewAuthToken(payload, options = {}) {
- if (options.updateSession) {
- const sessionData = await Session.findOne({ _id: options.updateSession })
-
- payload.session_uuid = sessionData.session_uuid
- } else {
- payload.session_uuid = global.nanoid()
- }
-
- const token = jwt.sign({
- session_uuid: payload.session_uuid,
- username: payload.username,
- user_id: payload.user_id,
- signLocation: payload.signLocation,
- }, global.jwtStrategy.secretOrKey, {
- expiresIn: global.jwtStrategy.expiresIn ?? "1h",
- algorithm: global.jwtStrategy.algorithm ?? "HS256"
- })
-
- return token
- }
-
- static async validate(token) {
- if (typeof token === "undefined") {
- throw new Error("Token is undefined")
- }
-
- let result = {
- expired: false,
- valid: true,
- data: null
- }
-
- await jwt.verify(token, global.jwtStrategy.secretOrKey, async (err, decoded) => {
- if (err) {
- result.valid = false
- result.error = err.message
-
- if (err.message === "jwt expired") {
- result.expired = true
- }
-
- return
- }
-
- result = { ...result, ...decoded }
-
- const sessions = await Session.find({ user_id: result.user_id })
- const sessionsTokens = sessions.map((session) => {
- if (session.user_id === result.user_id) {
- return session.token
- }
- })
-
- if (!sessionsTokens.includes(token)) {
- result.valid = false
- result.error = "Session token not found"
- } else {
- result.valid = true
- }
- })
-
- if (result.valid) {
- result.data = await jwt.decode(token)
- }
-
- return result
- }
-
- static async regenerate(expiredToken, refreshToken, aggregateData = {}) {
- // search for a regeneration token with the expired token (Should exist only one)
- const regenerationToken = await RegenerationToken.findOne({ refreshToken: refreshToken })
-
- if (!regenerationToken) {
- throw new Error("Cannot find regeneration token")
- }
-
- // check if the regeneration token is valid and not expired
- let decodedRefreshToken = null
- let decodedExpiredToken = null
-
- try {
- decodedRefreshToken = jwt.decode(refreshToken)
- decodedExpiredToken = jwt.decode(expiredToken)
- } catch (error) {
- console.error(error)
- // TODO: Storage this incident
- }
-
- if (!decodedRefreshToken) {
- throw new Error("Cannot decode refresh token")
- }
-
- if (!decodedExpiredToken) {
- throw new Error("Cannot decode expired token")
- }
-
- // is not needed to verify the expired token, because it suppossed to be expired
-
- // verify refresh token
- await jwt.verify(refreshToken, global.jwtStrategy.secretOrKey, async (err) => {
- // check if is expired
- if (err) {
- if (err.message === "jwt expired") {
- // check if server has enabled the enforcement of regeneration token expiration
- if (global.jwtStrategy.enforceRegenerationTokenExpiration) {
- // delete the regeneration token
- await RegenerationToken.deleteOne({ refreshToken: refreshToken })
-
- throw new Error("Regeneration token expired and cannot be regenerated due server has enabled enforcement security policy")
- }
- }
- }
-
- // check if the regeneration token is associated with the expired token
- if (decodedRefreshToken.expiredToken !== expiredToken) {
- throw new Error("Regeneration token is not associated with the expired token")
- }
- })
-
- // find the session associated with the expired token
- const session = await Session.findOne({ token: expiredToken })
-
- if (!session) {
- throw new Error("Cannot find session associated with the expired token")
- }
-
- // generate a new token
- const newToken = await this.createNewAuthToken({
- username: decodedExpiredToken.username,
- session_uuid: session.session_uuid,
- user_id: decodedExpiredToken.user_id,
- ip_address: aggregateData.ip_address,
- }, {
- updateSession: session._id,
- })
-
- // delete the regeneration token
- await RegenerationToken.deleteOne({ refreshToken: refreshToken })
-
- return newToken
- }
-
- static async createAuth(payload, options = {}) {
- const token = await this.createNewAuthToken(payload, options)
-
- const session = {
- token: token,
- session_uuid: payload.session_uuid,
- username: payload.username,
- user_id: payload.user_id,
- location: payload.signLocation,
- ip_address: payload.ip_address,
- client: payload.client,
- date: new Date().getTime(),
- }
-
- if (options.updateSession) {
- await Session.findByIdAndUpdate(options.updateSession, session)
- } else {
- let newSession = new Session(session)
-
- await newSession.save()
- }
-
- return token
- }
-
- static async createRegenerative(expiredToken) {
- // check if token is only expired, if is corrupted, reject
- let decoded = null
-
- try {
- decoded = jwt.decode(expiredToken)
- } catch (error) {
- console.error(error)
- }
-
- if (!decoded) {
- return false
- }
-
- // check if token exists on a session
- const sessions = await Session.find({ user_id: decoded.user_id })
- const currentSession = sessions.find((session) => session.token === expiredToken)
-
- if (!currentSession) {
- throw new Error("This token is not associated with any session")
- }
-
- // create a new refresh token and sign it with maximum expiration time of 1 day
- const refreshToken = jwt.sign(
- {
- expiredToken
- },
- global.jwtStrategy.secretOrKey,
- {
- expiresIn: "1d"
- }
- )
-
- // create a new regeneration token and save it
- const regenerationToken = new RegenerationToken({
- expiredToken,
- refreshToken,
- })
-
- await regenerationToken.save()
-
- // return the regeneration token
- return regenerationToken
- }
-
- static async getRegenerationToken(expiredToken) {
- const regenerationToken = await RegenerationToken.findOne({ expiredToken })
-
- return regenerationToken
- }
-}
\ No newline at end of file
diff --git a/packages/server/services/main/lib/videoTranscode/index.js b/packages/server/services/main/lib/videoTranscode/index.js
deleted file mode 100755
index 5a3b7df9..00000000
--- a/packages/server/services/main/lib/videoTranscode/index.js
+++ /dev/null
@@ -1,43 +0,0 @@
-import path from "path"
-
-const ffmpeg = require("fluent-ffmpeg")
-
-function videoTranscode(originalFilePath, outputPath, options = {}) {
- return new Promise((resolve, reject) => {
- const filename = path.basename(originalFilePath)
- const outputFilename = `${filename.split(".")[0]}_transcoded.${options.format ?? "webm"}`
- const outputFilepath = `${outputPath}/${outputFilename}`
-
- console.debug(`[TRANSCODING] Transcoding ${originalFilePath} to ${outputFilepath}`)
-
- const onEnd = async () => {
- console.debug(`[TRANSCODING] Finished transcode ${originalFilePath} to ${outputFilepath}`)
-
- return resolve({
- filepath: outputFilepath,
- filename: outputFilename,
- })
- }
-
- const onError = (err) => {
- console.error(`[TRANSCODING] Transcoding ${originalFilePath} to ${outputFilepath} failed`, err)
-
- return reject(err)
- }
-
- ffmpeg(originalFilePath)
- .audioBitrate(options.audioBitrate ?? 128)
- .videoBitrate(options.videoBitrate ?? 1024)
- .videoCodec(options.videoCodec ?? "libvpx")
- .audioCodec(options.audioCodec ?? "libvorbis")
- .format(options.format ?? "webm")
- .output(outputFilepath)
- .on("error", onError)
- .on("end", onEnd)
- .run()
- })
-}
-
-export {
- videoTranscode,
-}
\ No newline at end of file
diff --git a/packages/server/services/main/main.service.js b/packages/server/services/main/main.service.js
index d5d209fb..387c2f93 100755
--- a/packages/server/services/main/main.service.js
+++ b/packages/server/services/main/main.service.js
@@ -1,4 +1,4 @@
-import { Server } from "linebridge/src/server"
+import { Server } from "linebridge/dist/server"
import DbManager from "@shared-classes/DbManager"
diff --git a/packages/server/services/main/package.json b/packages/server/services/main/package.json
index 27c06dc5..aaa6e4ae 100755
--- a/packages/server/services/main/package.json
+++ b/packages/server/services/main/package.json
@@ -1,32 +1,7 @@
{
"name": "main",
"version": "0.60.2",
- "license": "MIT",
- "proxy": {
- "path": "/main",
- "port": 3010
- },
"dependencies": {
- "@octokit/rest": "^20.0.2",
- "@tensorflow/tfjs-node": "^4.17.0",
- "axios": "^1.6.7",
- "backblaze-b2": "^1.7.0",
- "bcrypt": "^5.1.1",
- "busboy": "^1.6.0",
- "connect-mongo": "^5.1.0",
- "content-range": "^2.0.2",
- "ioredis": "^5.3.2",
- "jsonwebtoken": "^9.0.2",
- "linebridge": "^0.16.0",
- "luxon": "^3.4.4",
- "mime-types": "^2.1.35",
- "minio": "^7.1.3",
- "moment": "^2.30.1",
- "moment-timezone": "^0.5.45",
- "mongoose": "^8.1.2",
- "normalize-url": "^8.0.0",
- "nsfwjs": "^3.0.0",
- "p-map": "^4.0.0",
- "p-queue": "^7.3.4"
+ "@octokit/rest": "^20.0.2"
}
}
diff --git a/packages/server/services/main/controllers/NFCController/endpoints/getTagById.js b/packages/server/services/main/routes/nfc/tag/id/[id]/delete.js
old mode 100755
new mode 100644
similarity index 55%
rename from packages/server/services/main/controllers/NFCController/endpoints/getTagById.js
rename to packages/server/services/main/routes/nfc/tag/id/[id]/delete.js
index 9eb9b56c..ff00b316
--- a/packages/server/services/main/controllers/NFCController/endpoints/getTagById.js
+++ b/packages/server/services/main/routes/nfc/tag/id/[id]/delete.js
@@ -1,8 +1,7 @@
-import { User, NFCTag } from "@db_models"
+import { NFCTag } from "@db_models"
export default {
- method: "GET",
- route: "/tags/:id",
+ middlewares: ["withAuthentication"],
fn: async (req, res) => {
let tag = await NFCTag.findOne({
_id: req.params.id
@@ -16,16 +15,14 @@ export default {
tag = tag.toObject()
- if (req.user) {
- if (tag.user_id.toString() === req.user._id.toString()) {
- tag.is_owner = true
- }
+ if (tag.user_id.toString() !== req.auth.session.user_id) {
+ throw new OperationError(403, "You do not own this tag")
}
- tag.user = await User.findOne({
- _id: tag.user_id
+ await NFCTag.deleteOne({
+ _id: tag._id.toString()
})
- return res.json(tag)
+ return tag
}
}
\ No newline at end of file
diff --git a/packages/server/services/main/routes/nfc/tag/id/[id]/get.js b/packages/server/services/main/routes/nfc/tag/id/[id]/get.js
new file mode 100644
index 00000000..0190c8c2
--- /dev/null
+++ b/packages/server/services/main/routes/nfc/tag/id/[id]/get.js
@@ -0,0 +1,27 @@
+import { User, NFCTag } from "@db_models"
+
+export default async (req, res) => {
+ let tag = await NFCTag.findOne({
+ _id: req.params.id
+ })
+
+ if (!tag) {
+ return res.status(404).json({
+ error: "Cannot find tag"
+ })
+ }
+
+ tag = tag.toObject()
+
+ if (req.user) {
+ if (tag.user_id.toString() === req.auth.session.user_id) {
+ tag.is_owner = true
+ }
+ }
+
+ tag.user = await User.findOne({
+ _id: tag.user_id
+ })
+
+ return tag
+}
\ No newline at end of file
diff --git a/packages/server/services/main/controllers/NFCController/endpoints/getTags.js b/packages/server/services/main/routes/nfc/tag/my/get.js
old mode 100755
new mode 100644
similarity index 64%
rename from packages/server/services/main/controllers/NFCController/endpoints/getTags.js
rename to packages/server/services/main/routes/nfc/tag/my/get.js
index 3758add0..351fa9bc
--- a/packages/server/services/main/controllers/NFCController/endpoints/getTags.js
+++ b/packages/server/services/main/routes/nfc/tag/my/get.js
@@ -1,14 +1,12 @@
import { NFCTag } from "@db_models"
export default {
- method: "GET",
- route: "/tags",
middlewares: ["withAuthentication"],
fn: async (req, res) => {
let tags = await NFCTag.find({
- user_id: req.user.id
+ user_id: req.auth.session.user_id
})
- return res.json(tags)
+ return tags
}
}
\ No newline at end of file
diff --git a/packages/server/services/main/controllers/NFCController/endpoints/registerTag.js b/packages/server/services/main/routes/nfc/tag/register/[serial]/post.js
old mode 100755
new mode 100644
similarity index 85%
rename from packages/server/services/main/controllers/NFCController/endpoints/registerTag.js
rename to packages/server/services/main/routes/nfc/tag/register/[serial]/post.js
index e9c9e903..25db4529
--- a/packages/server/services/main/controllers/NFCController/endpoints/registerTag.js
+++ b/packages/server/services/main/routes/nfc/tag/register/[serial]/post.js
@@ -9,18 +9,18 @@ const allowedUpdateFields = [
]
export default {
- method: "POST",
- route: "/tag/:serial",
middlewares: ["withAuthentication"],
fn: async (req, res) => {
let tag = await NFCTag.findOne({
serial: req.params.serial
})
+ const user_id = req.auth.session.user_id
+
if (!tag) {
tag = new NFCTag({
- user_id: req.user._id.toString(),
- owner_id: req.user._id.toString(),
+ user_id: user_id,
+ owner_id: user_id,
serial: req.params.serial,
alias: req.body.alias,
behavior: req.body.behavior,
@@ -34,7 +34,7 @@ export default {
tag = tag.toObject()
if (req.user) {
- if (tag.user_id !== req.user._id.toString()) {
+ if (tag.user_id !== user_id) {
return res.status(403).json({
error: `You do not own this tag`
})
@@ -58,6 +58,6 @@ export default {
}
}
- return res.json(tag)
+ return tag
}
}
\ No newline at end of file
diff --git a/packages/server/services/main/controllers/NFCController/endpoints/getTagBySerial.js b/packages/server/services/main/routes/nfc/tag/serial/get.js
old mode 100755
new mode 100644
similarity index 78%
rename from packages/server/services/main/controllers/NFCController/endpoints/getTagBySerial.js
rename to packages/server/services/main/routes/nfc/tag/serial/get.js
index 3d40408d..5fdc1de0
--- a/packages/server/services/main/controllers/NFCController/endpoints/getTagBySerial.js
+++ b/packages/server/services/main/routes/nfc/tag/serial/get.js
@@ -1,8 +1,6 @@
import { User, NFCTag } from "@db_models"
export default {
- method: "GET",
- route: "/tag/serial/:serial",
middlewares: ["withOptionalAuthentication"],
fn: async (req, res) => {
let tag = await NFCTag.findOne({
@@ -18,7 +16,7 @@ export default {
tag = tag.toObject()
if (req.user) {
- if (tag.user_id.toString() === req.user._id.toString()) {
+ if (tag.user_id.toString() === req.auth.session.user_id) {
tag.is_owner = true
}
}
@@ -27,6 +25,6 @@ export default {
_id: tag.user_id
})
- return res.json(tag)
+ return tag
}
}
\ No newline at end of file
diff --git a/packages/server/services/main/routes/repo/auto-update/mobile/get.js b/packages/server/services/main/routes/repo/auto-update/mobile/get.js
new file mode 100644
index 00000000..f47985bd
--- /dev/null
+++ b/packages/server/services/main/routes/repo/auto-update/mobile/get.js
@@ -0,0 +1,31 @@
+import { Octokit } from "@octokit/rest"
+
+const octokit = new Octokit({})
+
+export default async (req, res) => {
+ if (!process.env.GITHUB_REPO) {
+ return res.status(400).json({
+ error: "GITHUB_REPO env variable not set"
+ })
+ }
+
+ const lastRelease = await octokit.repos.getLatestRelease({
+ owner: process.env.GITHUB_REPO.split("/")[0],
+ repo: process.env.GITHUB_REPO.split("/")[1]
+ })
+
+ const bundle = lastRelease.data.assets.find((asset) => asset.name === "mobile_dist.zip")
+ const version = lastRelease.data.tag_name
+
+ if (!bundle) {
+ return res.status(400).json({
+ error: "mobile asset not available",
+ version: version,
+ })
+ }
+
+ return res.json({
+ url: bundle.browser_download_url,
+ version: version,
+ })
+}
\ No newline at end of file
diff --git a/packages/server/services/main/routes/repo/releases-notes/get.js b/packages/server/services/main/routes/repo/releases-notes/get.js
new file mode 100644
index 00000000..34b974cf
--- /dev/null
+++ b/packages/server/services/main/routes/repo/releases-notes/get.js
@@ -0,0 +1,45 @@
+import { Octokit } from "@octokit/rest"
+import axios from "axios"
+
+const octokit = new Octokit({})
+
+export default async (req, res) => {
+ if (!process.env.GITHUB_REPO) {
+ return res.status(400).json({
+ error: "GITHUB_REPO env variable not set"
+ })
+ }
+
+ const releasesNotes = []
+
+ // fetch the 3 latest releases
+ const releases = await octokit.repos.listReleases({
+ owner: process.env.GITHUB_REPO.split("/")[0],
+ repo: process.env.GITHUB_REPO.split("/")[1],
+ per_page: 3
+ })
+
+ for await (const release of releases.data) {
+ let changelogData = release.body
+
+ const bundle = release.assets.find((asset) => asset.name === "changelog.md")
+
+ if (bundle) {
+ const response = await axios.get(bundle.browser_download_url)
+ .catch(() => null)
+
+ if (response) {
+ changelogData = response.data
+ }
+ }
+
+ releasesNotes.push({
+ version: release.tag_name,
+ date: release.published_at,
+ body: changelogData,
+ isMd: bundle !== undefined
+ })
+ }
+
+ return res.json(releasesNotes)
+}
\ No newline at end of file
diff --git a/packages/server/services/main/services/fetchRemoteStreams/index.js b/packages/server/services/main/services/fetchRemoteStreams/index.js
deleted file mode 100755
index d2ee5e77..00000000
--- a/packages/server/services/main/services/fetchRemoteStreams/index.js
+++ /dev/null
@@ -1,78 +0,0 @@
-import axios from "axios"
-
-import { StreamingCategory, StreamingProfile, User } from "@db_models"
-
-import composeStreamingSources from "@utils/compose-streaming-sources"
-import lodash from "lodash"
-
-const streamingServerAPIAddress = process.env.STREAMING_API_SERVER ?? ""
-const streamingServerAPIUri = `${streamingServerAPIAddress.startsWith("https") ? "https" : "http"}://${streamingServerAPIAddress.split("://")[1]}`
-
-export default async (stream_id) => {
- let apiURI = `${streamingServerAPIUri}/streams`
-
- // fetch all streams from api
- let { data } = await axios({
- method: "GET",
- url: apiURI,
- params: {
- stream: stream_id,
- }
- }).catch((err) => {
- console.error(err)
- return false
- })
-
- let streamings = []
-
- if (!data) return streamings
-
- if (stream_id) {
- streamings.push(data)
- } else {
- streamings = data
- }
-
- streamings = streamings.map(async (entry) => {
- const { stream, profile_id } = entry
-
- let profile = await StreamingProfile.findById(profile_id)
-
- if (!profile) return null
-
- profile = profile.toObject()
-
- profile._id = profile._id.toString()
-
- profile.info.category = await StreamingCategory.findOne({
- key: profile.info.category
- })
-
- let user = await User.findById(profile.user_id)
-
- if (!user) return null
-
- user = user.toObject()
-
- const sources = composeStreamingSources(user.username, profile._id)
-
- return {
- profile_id: profile._id,
- info: profile.info,
- name: stream,
- streamUrl: `${user.username}?profile=${profile._id}`,
- sources: lodash.pick(sources, ["rtmp", "hls", "flv", "aac"]),
- user,
- }
- })
-
- streamings = await Promise.all(streamings)
-
- streamings = streamings.filter((stream) => stream !== null)
-
- if (stream_id) {
- return streamings[0]
- }
-
- return streamings
-}
\ No newline at end of file
diff --git a/packages/server/services/main/services/getMutuals/index.js b/packages/server/services/main/services/getMutuals/index.js
deleted file mode 100755
index 36eaabd9..00000000
--- a/packages/server/services/main/services/getMutuals/index.js
+++ /dev/null
@@ -1,30 +0,0 @@
-import { User, UserFollow } from "@db_models"
-
-// TODO: Sort follows by last activity
-export default async (payload = {}) => {
- const from_user_id = payload.from_user_id
-
- if (!from_user_id) {
- throw new Error("Missing from_user_id")
- }
-
- let mutuals = []
-
- // load friends and recents users
- const follows = await UserFollow.find({
- user_id: from_user_id,
- })
- .limit(15)
-
- mutuals = await UserFollow.find({
- user_id: follows.map((follow) => follow.to.toString()),
- to: from_user_id,
- })
-
- // load data user
- mutuals = await User.find({
- _id: mutuals.map((mutual) => mutual.user_id.toString()),
- })
-
- return mutuals
-}
\ No newline at end of file
diff --git a/packages/server/services/main/services/newStreamingProfile/index.js b/packages/server/services/main/services/newStreamingProfile/index.js
deleted file mode 100755
index d22ff253..00000000
--- a/packages/server/services/main/services/newStreamingProfile/index.js
+++ /dev/null
@@ -1,28 +0,0 @@
-import { StreamingProfile } from "@db_models"
-
-export default async (profile = {}) => {
- if (!profile.user_id) {
- throw new Error("Invalid request, missing user_id")
- }
-
- if (!profile.profile_name) {
- throw new Error("Invalid request, missing profile_name")
- }
-
- const newProfile = new StreamingProfile({
- user_id: profile.user_id,
- profile_name: profile.profile_name,
- stream_key: global.nanoid(),
- info: {
- title: "Untitled",
- description: "No description",
- category: "other",
- thumbnail: null,
- ...profile.info,
- }
- })
-
- await newProfile.save()
-
- return newProfile
-}
\ No newline at end of file
diff --git a/packages/server/services/main/utils/aggregate-error/index.js b/packages/server/services/main/utils/aggregate-error/index.js
deleted file mode 100755
index 3ae0e5c2..00000000
--- a/packages/server/services/main/utils/aggregate-error/index.js
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright (c) Sindre Sorhus
(https://sindresorhus.com)
-import indentString from '../indent-string';
-import cleanStack from '../clean-stack';
-
-const cleanInternalStack = stack => stack.replace(/\s+at .*aggregate-error\/index.js:\d+:\d+\)?/g, '');
-
-export default class AggregateError extends Error {
- #errors;
-
- name = 'AggregateError';
-
- constructor(errors) {
- if (!Array.isArray(errors)) {
- throw new TypeError(`Expected input to be an Array, got ${typeof errors}`);
- }
-
- errors = errors.map(error => {
- if (error instanceof Error) {
- return error;
- }
-
- if (error !== null && typeof error === 'object') {
- // Handle plain error objects with message property and/or possibly other metadata
- return Object.assign(new Error(error.message), error);
- }
-
- return new Error(error);
- });
-
- let message = errors
- .map(error => {
- // The `stack` property is not standardized, so we can't assume it exists
- return typeof error.stack === 'string' && error.stack.length > 0 ? cleanInternalStack(cleanStack(error.stack)) : String(error);
- })
- .join('\n');
- message = '\n' + indentString(message, 4);
- super(message);
-
- this.#errors = errors;
- }
-
- get errors() {
- return this.#errors.slice();
- }
-}
\ No newline at end of file
diff --git a/packages/server/services/main/utils/clean-stack/index.js b/packages/server/services/main/utils/clean-stack/index.js
deleted file mode 100755
index 01dfcfce..00000000
--- a/packages/server/services/main/utils/clean-stack/index.js
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright (c) Sindre Sorhus (https://sindresorhus.com)
-import os from 'os';
-import escapeStringRegexp from '../escape-string-regexp';
-
-const extractPathRegex = /\s+at.*[(\s](.*)\)?/;
-const pathRegex = /^(?:(?:(?:node|node:[\w/]+|(?:(?:node:)?internal\/[\w/]*|.*node_modules\/(?:babel-polyfill|pirates)\/.*)?\w+)(?:\.js)?:\d+:\d+)|native)/;
-const homeDir = typeof os.homedir === 'undefined' ? '' : os.homedir().replace(/\\/g, '/');
-
-export default function cleanStack(stack, {pretty = false, basePath} = {}) {
- const basePathRegex = basePath && new RegExp(`(at | \\()${escapeStringRegexp(basePath.replace(/\\/g, '/'))}`, 'g');
-
- if (typeof stack !== 'string') {
- return undefined;
- }
-
- return stack.replace(/\\/g, '/')
- .split('\n')
- .filter(line => {
- const pathMatches = line.match(extractPathRegex);
- if (pathMatches === null || !pathMatches[1]) {
- return true;
- }
-
- const match = pathMatches[1];
-
- // Electron
- if (
- match.includes('.app/Contents/Resources/electron.asar') ||
- match.includes('.app/Contents/Resources/default_app.asar') ||
- match.includes('node_modules/electron/dist/resources/electron.asar') ||
- match.includes('node_modules/electron/dist/resources/default_app.asar')
- ) {
- return false;
- }
-
- return !pathRegex.test(match);
- })
- .filter(line => line.trim() !== '')
- .map(line => {
- if (basePathRegex) {
- line = line.replace(basePathRegex, '$1');
- }
-
- if (pretty) {
- line = line.replace(extractPathRegex, (m, p1) => m.replace(p1, p1.replace(homeDir, '~')));
- }
-
- return line;
- })
- .join('\n');
-}
\ No newline at end of file
diff --git a/packages/server/services/main/utils/compose-streaming-sources/index.js b/packages/server/services/main/utils/compose-streaming-sources/index.js
deleted file mode 100755
index 29214462..00000000
--- a/packages/server/services/main/utils/compose-streaming-sources/index.js
+++ /dev/null
@@ -1,16 +0,0 @@
-const streamingServerAPIAddress = process.env.STREAMING_API_SERVER ?? ""
-
-const streamingServerAPIUri = `${streamingServerAPIAddress.startsWith("https") ? "https" : "http"}://${streamingServerAPIAddress.split("://")[1]}`
-
-export default (username, profile_id) => {
- const streamId = `${username}${profile_id ? `__${profile_id}` : ""}`
-
- return {
- ingest: process.env.STREAMING_INGEST_SERVER,
- rtmp: `${streamingServerAPIUri}/${streamId}`,
- rtsp: `rtsp://${process.env.STREAMING_INGEST_SERVER}:8554/live/${streamId}`,
- hls: `${streamingServerAPIUri}/stream/hls/${streamId}`,
- flv: `${streamingServerAPIUri}/stream/flv/${streamId}`,
- mp3: `${streamingServerAPIUri}/stream/mp3/${streamId}`,
- }
-}
\ No newline at end of file
diff --git a/packages/server/services/main/utils/createTokenRegeneration/index.js b/packages/server/services/main/utils/createTokenRegeneration/index.js
deleted file mode 100755
index 993fb901..00000000
--- a/packages/server/services/main/utils/createTokenRegeneration/index.js
+++ /dev/null
@@ -1,17 +0,0 @@
-import Token from "@lib/token"
-
-export default async (expiredToken) => {
- let regenerationToken = null
-
- // check if this expired token has a regeneration token associated
- const associatedRegenerationToken = await Token.getRegenerationToken(expiredToken)
-
- if (associatedRegenerationToken) {
- regenerationToken = associatedRegenerationToken.refreshToken
- } else {
- // create a new regeneration token with the expired token
- regenerationToken = await Token.createRegenerative(expiredToken)
- }
-
- return regenerationToken.refreshToken
-}
\ No newline at end of file
diff --git a/packages/server/services/main/utils/download-file/index.js b/packages/server/services/main/utils/download-file/index.js
deleted file mode 100755
index 5c51c07f..00000000
--- a/packages/server/services/main/utils/download-file/index.js
+++ /dev/null
@@ -1,39 +0,0 @@
-import fs from "fs"
-import path from "path"
-import axios from "axios"
-
-export default async (payload) => {
- return new Promise(async (resolve, reject) => {
- try {
- let { url, destination } = payload
-
- // if destination path is not provided, use cache folder
- if (!destination) {
- destination = path.resolve(global.uploadCachePath, path.basename(url))
- }
-
- const writer = fs.createWriteStream(destination)
-
- if (!writer) {
- return false
- }
-
- const response = await axios({
- url,
- method: "GET",
- responseType: "stream"
- })
-
- response.data.pipe(writer)
-
- writer.on("finish", () => resolve({
- destination,
- delete: () => fs.unlinkSync(destination),
- read: () => fs.readFileSync(destination),
- }))
- writer.on("error", reject)
- } catch (error) {
- reject(error)
- }
- })
-}
\ No newline at end of file
diff --git a/packages/server/services/main/utils/escape-string-regexp/index.js b/packages/server/services/main/utils/escape-string-regexp/index.js
deleted file mode 100755
index d49baa45..00000000
--- a/packages/server/services/main/utils/escape-string-regexp/index.js
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright (c) Sindre Sorhus (https://sindresorhus.com)
-export default function escapeStringRegexp(string) {
- if (typeof string !== 'string') {
- throw new TypeError('Expected a string');
- }
-
- // Escape characters with special meaning either inside or outside character sets.
- // Use a simple backslash escape when it’s always valid, and a `\xnn` escape when the simpler form would be disallowed by Unicode patterns’ stricter grammar.
- return string
- .replace(/[|\\{}()[\]^$+*?.]/g, '\\$&')
- .replace(/-/g, '\\x2d');
-}
\ No newline at end of file
diff --git a/packages/server/services/main/utils/fullfillPostsData/index.js b/packages/server/services/main/utils/fullfillPostsData/index.js
deleted file mode 100755
index 33abd8fc..00000000
--- a/packages/server/services/main/utils/fullfillPostsData/index.js
+++ /dev/null
@@ -1,94 +0,0 @@
-import { User, Comment, PostLike, SavedPost } from "@db_models"
-
-export default async (payload) => {
- let {
- posts,
- for_user_id,
- } = payload
-
- if (!Array.isArray(posts)) {
- posts = [posts]
- }
-
- let savedPostsIds = []
-
- if (for_user_id) {
- const savedPosts = await SavedPost.find({ user_id: for_user_id })
- .sort({ saved_at: -1 })
-
- savedPostsIds = savedPosts.map((savedPost) => savedPost.post_id)
- }
-
- let [usersData, likesData, commentsData] = await Promise.all([
- User.find({
- _id: {
- $in: posts.map((post) => post.user_id)
- }
- }),
- PostLike.find({
- post_id: {
- $in: posts.map((post) => post._id)
- }
- }).catch(() => []),
- Comment.find({
- parent_id: {
- $in: posts.map((post) => post._id)
- }
- }).catch(() => []),
- ])
-
- // wrap likesData by post_id
- likesData = likesData.reduce((acc, like) => {
- if (!acc[like.post_id]) {
- acc[like.post_id] = []
- }
-
- acc[like.post_id].push(like)
-
- return acc
- }, {})
-
- // wrap commentsData by post_id
- commentsData = commentsData.reduce((acc, comment) => {
- if (!acc[comment.parent_id]) {
- acc[comment.parent_id] = []
- }
-
- acc[comment.parent_id].push(comment)
-
- return acc
- }, {})
-
- posts = await Promise.all(posts.map(async (post, index) => {
- post = post.toObject()
-
- let user = usersData.find((user) => user._id.toString() === post.user_id.toString())
-
- if (!user) {
- user = {
- username: "Deleted user",
- }
- }
-
- let likes = likesData[post._id.toString()] ?? []
-
- post.countLikes = likes.length
-
- let comments = commentsData[post._id.toString()] ?? []
-
- post.countComments = comments.length
-
- if (for_user_id) {
- post.isLiked = likes.some((like) => like.user_id.toString() === for_user_id)
- post.isSaved = savedPostsIds.includes(post._id.toString())
- }
-
- return {
- ...post,
- comments: comments.map((comment) => comment._id.toString()),
- user,
- }
- }))
-
- return posts
-}
\ No newline at end of file
diff --git a/packages/server/services/main/utils/image-byte-array/index.js b/packages/server/services/main/utils/image-byte-array/index.js
deleted file mode 100755
index 4c1e6454..00000000
--- a/packages/server/services/main/utils/image-byte-array/index.js
+++ /dev/null
@@ -1,14 +0,0 @@
-export default (image, numChannels) => {
- const pixels = image.data
- const numPixels = image.width * image.height
-
- const values = new Int32Array(numPixels * numChannels)
-
- for (let i = 0; i < numPixels; i++) {
- for (let channel = 0; channel < numChannels; ++channel) {
- values[i * numChannels + channel] = pixels[i * 4 + channel]
- }
- }
-
- return values
-}
\ No newline at end of file
diff --git a/packages/server/services/main/utils/indecent-prediction/index.js b/packages/server/services/main/utils/indecent-prediction/index.js
deleted file mode 100755
index 1749c440..00000000
--- a/packages/server/services/main/utils/indecent-prediction/index.js
+++ /dev/null
@@ -1,73 +0,0 @@
-const tf = require("@tensorflow/tfjs-node")
-
-import * as nsfwjs from "nsfwjs/dist"
-import sharp from "sharp"
-
-import fs from "fs"
-import path from "path"
-
-import downloadFile from "../download-file"
-import readImage from "../read-image"
-import imageByteArray from "../image-byte-array"
-
-const imageToInput = (image, numChannels) => {
- const values = imageByteArray(image, numChannels)
- const outShape = [image.height, image.width, numChannels]
- const input = tf.tensor3d(values, outShape, "int32")
-
- return input
-}
-
-if (global.isProduction) {
- tf.enableProdMode()
-}
-
-export default async (payload) => {
- try {
- let { url, image, channels = 3 } = payload
-
- let file = null
- const model = await nsfwjs.load()
-
- if (!image && url) {
- file = await downloadFile({ url })
-
- image = file.destination
- }
-
- // check if image is not a jpg
- if (image.indexOf(".jpg") === -1) {
- // convert image to jpg
- const converted = await sharp(image)
- .jpeg()
- .toBuffer()
-
- // write converted image to disk (use cache)
- const destination = path.resolve(global.uploadCachePath, `${Date.now()}.jpg`)
-
- fs.writeFileSync(destination, converted)
-
- // set image to the converted image
- file = {
- destination,
- delete: () => fs.unlinkSync(destination),
- }
-
- image = destination
- }
-
- const logo = readImage(image)
- const input = imageToInput(logo, channels)
-
- const predictions = await model.classify(input)
-
- if (typeof file.delete === "function") {
- await file.delete()
- }
-
- return predictions
- } catch (error) {
- console.error(`Failed to process image >`, error)
- console.trace()
- }
-}
\ No newline at end of file
diff --git a/packages/server/services/main/utils/indent-string/index.js b/packages/server/services/main/utils/indent-string/index.js
deleted file mode 100755
index eafd265a..00000000
--- a/packages/server/services/main/utils/indent-string/index.js
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright (c) Sindre Sorhus (https://sindresorhus.com)
-export default function indentString(string, count = 1, options = {}) {
- const {
- indent = ' ',
- includeEmptyLines = false
- } = options;
-
- if (typeof string !== 'string') {
- throw new TypeError(
- `Expected \`input\` to be a \`string\`, got \`${typeof string}\``
- );
- }
-
- if (typeof count !== 'number') {
- throw new TypeError(
- `Expected \`count\` to be a \`number\`, got \`${typeof count}\``
- );
- }
-
- if (count < 0) {
- throw new RangeError(
- `Expected \`count\` to be at least 0, got \`${count}\``
- );
- }
-
- if (typeof indent !== 'string') {
- throw new TypeError(
- `Expected \`options.indent\` to be a \`string\`, got \`${typeof indent}\``
- );
- }
-
- if (count === 0) {
- return string;
- }
-
- const regex = includeEmptyLines ? /^/gm : /^(?!\s*$)/gm;
-
- return string.replace(regex, indent.repeat(count));
-}
\ No newline at end of file
diff --git a/packages/server/services/main/utils/is-nsfw/index.js b/packages/server/services/main/utils/is-nsfw/index.js
deleted file mode 100755
index 538ac704..00000000
--- a/packages/server/services/main/utils/is-nsfw/index.js
+++ /dev/null
@@ -1,22 +0,0 @@
-const minumunPredictions = {
- "Hentai": 0.8,
- "Porn": 0.7,
-}
-
-export default (predictions) => {
- if (!Array.isArray(predictions)) {
- throw new Error("predictions must be an array")
- }
-
- let isNsfw = false
-
- Object.keys(minumunPredictions).forEach((key) => {
- const prediction = predictions.find((prediction) => prediction.className === key)
-
- if (prediction && prediction.probability >= minumunPredictions[key]) {
- isNsfw = true
- }
- })
-
- return isNsfw
-}
\ No newline at end of file
diff --git a/packages/server/services/main/utils/pMap/index.js b/packages/server/services/main/utils/pMap/index.js
deleted file mode 100755
index 7a47c36c..00000000
--- a/packages/server/services/main/utils/pMap/index.js
+++ /dev/null
@@ -1,198 +0,0 @@
-// Copyright (c) Sindre Sorhus (https://sindresorhus.com)
-import AggregateError from "../aggregate-error";
-
-/**
-An error to be thrown when the request is aborted by AbortController.
-DOMException is thrown instead of this Error when DOMException is available.
-*/
-export class AbortError extends Error {
- constructor(message) {
- super();
- this.name = "AbortError";
- this.message = message;
- }
-}
-
-/**
-TODO: Remove AbortError and just throw DOMException when targeting Node 18.
-*/
-const getDOMException = errorMessage => globalThis.DOMException === undefined
- ? new AbortError(errorMessage)
- : new DOMException(errorMessage);
-
-/**
-TODO: Remove below function and just "reject(signal.reason)" when targeting Node 18.
-*/
-const getAbortedReason = signal => {
- const reason = signal.reason === undefined
- ? getDOMException("This operation was aborted.")
- : signal.reason;
-
- return reason instanceof Error ? reason : getDOMException(reason);
-};
-
-export default async function pMap(
- iterable,
- mapper,
- {
- concurrency = Number.POSITIVE_INFINITY,
- stopOnError = true,
- signal,
- } = {},
-) {
- return new Promise((resolve, reject_) => {
- if (iterable[Symbol.iterator] === undefined && iterable[Symbol.asyncIterator] === undefined) {
- throw new TypeError(`Expected \`input\` to be either an \`Iterable\` or \`AsyncIterable\`, got (${typeof iterable})`);
- }
-
- if (typeof mapper !== "function") {
- throw new TypeError("Mapper function is required");
- }
-
- if (!((Number.isSafeInteger(concurrency) || concurrency === Number.POSITIVE_INFINITY) && concurrency >= 1)) {
- throw new TypeError(`Expected \`concurrency\` to be an integer from 1 and up or \`Infinity\`, got \`${concurrency}\` (${typeof concurrency})`);
- }
-
- const result = [];
- const errors = [];
- const skippedIndexesMap = new Map();
- let isRejected = false;
- let isResolved = false;
- let isIterableDone = false;
- let resolvingCount = 0;
- let currentIndex = 0;
- const iterator = iterable[Symbol.iterator] === undefined ? iterable[Symbol.asyncIterator]() : iterable[Symbol.iterator]();
-
- const reject = reason => {
- isRejected = true;
- isResolved = true;
- reject_(reason);
- };
-
- if (signal) {
- if (signal.aborted) {
- reject(getAbortedReason(signal));
- }
-
- signal.addEventListener("abort", () => {
- reject(getAbortedReason(signal));
- });
- }
-
- const next = async () => {
- if (isResolved) {
- return;
- }
-
- const nextItem = await iterator.next();
-
- const index = currentIndex;
- currentIndex++;
-
- // Note: `iterator.next()` can be called many times in parallel.
- // This can cause multiple calls to this `next()` function to
- // receive a `nextItem` with `done === true`.
- // The shutdown logic that rejects/resolves must be protected
- // so it runs only one time as the `skippedIndex` logic is
- // non-idempotent.
- if (nextItem.done) {
- isIterableDone = true;
-
- if (resolvingCount === 0 && !isResolved) {
- if (!stopOnError && errors.length > 0) {
- reject(new AggregateError(errors));
- return;
- }
-
- isResolved = true;
-
- if (skippedIndexesMap.size === 0) {
- resolve(result);
- return;
- }
-
- const pureResult = [];
-
- // Support multiple `pMapSkip`"s.
- for (const [index, value] of result.entries()) {
- if (skippedIndexesMap.get(index) === pMapSkip) {
- continue;
- }
-
- pureResult.push(value);
- }
-
- resolve(pureResult);
- }
-
- return;
- }
-
- resolvingCount++;
-
- // Intentionally detached
- (async () => {
- try {
- const element = await nextItem.value;
-
- if (isResolved) {
- return;
- }
-
- const value = await mapper(element, index);
-
- // Use Map to stage the index of the element.
- if (value === pMapSkip) {
- skippedIndexesMap.set(index, value);
- }
-
- result[index] = value;
-
- resolvingCount--;
- await next();
- } catch (error) {
- if (stopOnError) {
- reject(error);
- } else {
- errors.push(error);
- resolvingCount--;
-
- // In that case we can"t really continue regardless of `stopOnError` state
- // since an iterable is likely to continue throwing after it throws once.
- // If we continue calling `next()` indefinitely we will likely end up
- // in an infinite loop of failed iteration.
- try {
- await next();
- } catch (error) {
- reject(error);
- }
- }
- }
- })();
- };
-
- // Create the concurrent runners in a detached (non-awaited)
- // promise. We need this so we can await the `next()` calls
- // to stop creating runners before hitting the concurrency limit
- // if the iterable has already been marked as done.
- // NOTE: We *must* do this for async iterators otherwise we"ll spin up
- // infinite `next()` calls by default and never start the event loop.
- (async () => {
- for (let index = 0; index < concurrency; index++) {
- try {
- // eslint-disable-next-line no-await-in-loop
- await next();
- } catch (error) {
- reject(error);
- break;
- }
-
- if (isIterableDone || isRejected) {
- break;
- }
- }
- })();
- });
-}
-
-export const pMapSkip = Symbol("skip");
\ No newline at end of file
diff --git a/packages/server/services/main/utils/read-image/index.js b/packages/server/services/main/utils/read-image/index.js
deleted file mode 100755
index cf34758e..00000000
--- a/packages/server/services/main/utils/read-image/index.js
+++ /dev/null
@@ -1,9 +0,0 @@
-import fs from "fs"
-import jpeg from "jpeg-js"
-
-export default (path) => {
- const buf = fs.readFileSync(path)
- const pixels = jpeg.decode(buf, true)
-
- return pixels
-}
\ No newline at end of file
diff --git a/packages/server/services/marketplace/marketplace.service.js b/packages/server/services/marketplace/marketplace.service.js
index d18bad45..7356ec43 100755
--- a/packages/server/services/marketplace/marketplace.service.js
+++ b/packages/server/services/marketplace/marketplace.service.js
@@ -1,4 +1,4 @@
-import { Server } from "linebridge/src/server"
+import { Server } from "linebridge/dist/server"
import DbManager from "@shared-classes/DbManager"
import RedisClient from "@shared-classes/RedisClient"
diff --git a/packages/server/services/marketplace/package.json b/packages/server/services/marketplace/package.json
index 5ae41dc4..4aaff239 100755
--- a/packages/server/services/marketplace/package.json
+++ b/packages/server/services/marketplace/package.json
@@ -1,37 +1,9 @@
{
"name": "marketplace",
"version": "0.60.2",
- "license": "MIT",
"dependencies": {
"7zip-min": "^1.4.4",
- "@foxify/events": "^2.1.0",
"@octokit/rest": "^19.0.7",
- "axios": "^1.2.5",
- "bcrypt": "^5.1.0",
- "busboy": "^1.6.0",
- "comty.js": "^0.58.2",
- "connect-mongo": "^4.6.0",
- "content-range": "^2.0.2",
- "dotenv": "^16.0.3",
- "form-data": "^4.0.0",
- "formidable": "^2.1.1",
- "hyper-express": "^6.5.9",
- "jsonwebtoken": "^9.0.0",
- "linebridge": "0.15.12",
- "live-directory": "^3.0.3",
- "luxon": "^3.2.1",
- "merge-files": "^0.1.2",
- "mime-types": "^2.1.35",
- "minio": "^7.0.32",
- "moment": "^2.29.4",
- "moment-timezone": "^0.5.40",
- "mongoose": "^6.9.0",
- "normalize-url": "^8.0.0",
- "p-map": "^6.0.0",
- "p-queue": "^7.3.4",
- "redis": "^4.6.6",
- "sharp": "^0.31.3",
- "split-chunk-merge": "^1.0.0",
"sucrase": "^3.32.0",
"uglify-js": "^3.17.4"
}
diff --git a/packages/server/services/music/classes/track/methods/create.js b/packages/server/services/music/classes/track/methods/create.js
index 71f8e45f..2f0d25ac 100644
--- a/packages/server/services/music/classes/track/methods/create.js
+++ b/packages/server/services/music/classes/track/methods/create.js
@@ -26,7 +26,7 @@ export default async (payload = {}) => {
mimeType: headers["content-type"],
})
- const metadata = {
+ let metadata = {
format: fileMetadata.format.codec,
channels: fileMetadata.format.numberOfChannels,
sampleRate: fileMetadata.format.sampleRate,
diff --git a/packages/server/services/music/controllers/playlists/routes/get/self.js b/packages/server/services/music/controllers/playlists/routes/get/self.js
index 5d35ea66..0af4af23 100755
--- a/packages/server/services/music/controllers/playlists/routes/get/self.js
+++ b/packages/server/services/music/controllers/playlists/routes/get/self.js
@@ -24,8 +24,8 @@ export default async (req, res) => {
}
}
- const playlistsCount = await Playlist.count(searchQuery)
- const releasesCount = await Release.count(searchQuery)
+ const playlistsCount = await Playlist.countDocuments(searchQuery)
+ const releasesCount = await Release.countDocuments(searchQuery)
let total_length = playlistsCount + releasesCount
diff --git a/packages/server/services/music/controllers/releases/routes/get/self.js b/packages/server/services/music/controllers/releases/routes/get/self.js
index 6586db33..a566d69d 100755
--- a/packages/server/services/music/controllers/releases/routes/get/self.js
+++ b/packages/server/services/music/controllers/releases/routes/get/self.js
@@ -24,7 +24,7 @@ export default async (req, res) => {
}
}
- const total_length = await Release.count(searchQuery)
+ const total_length = await Release.countDocuments(searchQuery)
let releases = await Release.find(searchQuery)
.sort({ created_at: -1 })
diff --git a/packages/server/services/music/controllers/releases/routes/get/user/[user_id].js b/packages/server/services/music/controllers/releases/routes/get/user/[user_id].js
index a00507e1..c7a64b12 100755
--- a/packages/server/services/music/controllers/releases/routes/get/user/[user_id].js
+++ b/packages/server/services/music/controllers/releases/routes/get/user/[user_id].js
@@ -8,7 +8,7 @@ export default async (req, res) => {
const { user_id } = req.params
const { keywords, limit = 10, offset = 0 } = req.query
- const total_length = await Release.count({
+ const total_length = await Release.countDocuments({
user_id,
})
diff --git a/packages/server/services/music/controllers/tracks/routes/get/liked.js b/packages/server/services/music/controllers/tracks/routes/get/liked.js
index 8a2b661b..6413e760 100755
--- a/packages/server/services/music/controllers/tracks/routes/get/liked.js
+++ b/packages/server/services/music/controllers/tracks/routes/get/liked.js
@@ -9,7 +9,7 @@ export default async (req, res) => {
const { limit = 100, offset = 0 } = req.query
- let totalLikedTracks = await TrackLike.count({
+ let totalLikedTracks = await TrackLike.countDocuments({
user_id: req.session.user_id,
})
diff --git a/packages/server/services/music/getPlaylistsFromFollowing.js b/packages/server/services/music/getPlaylistsFromFollowing.js
deleted file mode 100755
index 9faac13d..00000000
--- a/packages/server/services/music/getPlaylistsFromFollowing.js
+++ /dev/null
@@ -1,42 +0,0 @@
-import { Playlist, User, UserFollow } from "@db_models"
-
-export default async (payload) => {
- const {
- for_user_id,
- limit = 20,
- skip = 0,
- } = payload
-
- // get post from users that the user follows
- const followingUsers = await UserFollow.find({
- user_id: for_user_id
- })
-
- const followingUserIds = followingUsers.map((followingUser) => followingUser.to)
-
- const fetchFromUserIds = [
- for_user_id,
- ...followingUserIds,
- ]
-
- // firter out the playlists that are not public
- let playlists = await Playlist.find({
- user_id: { $in: fetchFromUserIds },
- $or: [
- { public: true },
- ]
- })
- .sort({ created_at: -1 })
- .limit(limit)
- .skip(skip)
-
- playlists = Promise.all(playlists.map(async (playlist) => {
- playlist = playlist.toObject()
-
- playlist.type = "playlist"
-
- return playlist
- }))
-
- return playlists
-}
\ No newline at end of file
diff --git a/packages/server/services/music/getReleasesFromFollowing.js b/packages/server/services/music/getReleasesFromFollowing.js
deleted file mode 100755
index bd35e20f..00000000
--- a/packages/server/services/music/getReleasesFromFollowing.js
+++ /dev/null
@@ -1,40 +0,0 @@
-import { Release, UserFollow } from "@db_models"
-
-export default async (payload) => {
- const {
- for_user_id,
- limit = 20,
- skip = 0,
- } = payload
-
- // get post from users that the user follows
- const followingUsers = await UserFollow.find({
- user_id: for_user_id
- })
-
- const followingUserIds = followingUsers.map((followingUser) => followingUser.to)
-
- const fetchFromUserIds = [
- for_user_id,
- ...followingUserIds,
- ]
-
- // firter out the releases that are not public
- let releases = await Release.find({
- user_id: { $in: fetchFromUserIds },
- $or: [
- { public: true },
- ]
- })
- .sort({ created_at: -1 })
- .limit(limit)
- .skip(skip)
-
- releases = Promise.all(releases.map(async (release) => {
- release = release.toObject()
-
- return release
- }))
-
- return releases
-}
\ No newline at end of file
diff --git a/packages/server/services/music/music.service.js b/packages/server/services/music/music.service.js
index 4b5aca73..33b70587 100755
--- a/packages/server/services/music/music.service.js
+++ b/packages/server/services/music/music.service.js
@@ -1,4 +1,4 @@
-import { Server } from "linebridge/src/server"
+import { Server } from "linebridge/dist/server"
import DbManager from "@shared-classes/DbManager"
diff --git a/packages/server/services/music/package.json b/packages/server/services/music/package.json
index ca9a3a24..e230c3e0 100755
--- a/packages/server/services/music/package.json
+++ b/packages/server/services/music/package.json
@@ -1,33 +1,9 @@
{
"name": "music",
"version": "0.60.2",
- "license": "MIT",
- "proxyMount": "/music",
- "proxy": {
- "path": "/main",
- "port": 3050
- },
"dependencies": {
- "@foxify/events": "^2.1.0",
- "axios": "^1.4.0",
- "bcrypt": "5.0.1",
- "comty.js": "^0.58.2",
- "connect-mongo": "^4.6.0",
- "cors": "^2.8.5",
- "dotenv": "^16.0.3",
- "express": "^4.18.2",
- "jsonwebtoken": "8.5.1",
- "linebridge": "0.15.12",
- "luxon": "^3.0.4",
- "minio": "^7.0.32",
- "moment": "2.29.4",
- "moment-timezone": "0.5.37",
- "mongoose": "^6.9.0",
- "morgan": "^1.10.0",
"ms": "^2.1.3",
"music-metadata": "^7.14.0",
- "openai": "^4.47.2",
- "redis": "^4.6.6",
- "socket.io": "^4.5.4"
+ "openai": "^4.47.2"
}
}
diff --git a/packages/server/services/music/routes/music/feed/get.js b/packages/server/services/music/routes/music/feed/get.js
index 4957499a..a355ea5f 100644
--- a/packages/server/services/music/routes/music/feed/get.js
+++ b/packages/server/services/music/routes/music/feed/get.js
@@ -5,7 +5,7 @@ export default async (req) => {
const searchQuery = {}
- const total_length = await MusicRelease.count(searchQuery)
+ const total_length = await MusicRelease.countDocuments(searchQuery)
let result = await MusicRelease.find(searchQuery)
.limit(limit)
diff --git a/packages/server/services/music/routes/music/releases/self/get.js b/packages/server/services/music/routes/music/releases/self/get.js
index b838b553..bb89b610 100644
--- a/packages/server/services/music/routes/music/releases/self/get.js
+++ b/packages/server/services/music/routes/music/releases/self/get.js
@@ -39,7 +39,7 @@ export default {
}
return {
- total_length: await MusicRelease.count(searchQuery),
+ total_length: await MusicRelease.countDocuments(searchQuery),
items: releases,
}
}
diff --git a/packages/server/services/music/services/findSpotifyId.js b/packages/server/services/music/services/findSpotifyId.js
deleted file mode 100755
index 0dacc812..00000000
--- a/packages/server/services/music/services/findSpotifyId.js
+++ /dev/null
@@ -1,45 +0,0 @@
-const clearQueryRegexs = [
- // remove titles with (feat. Something)
- new RegExp(/\(feat\..*\)/, "gi"),
- // remplace $ with S
- new RegExp(/\$/, "gi"),
- // remove special characters
- new RegExp(/[\(\)\[\]\$\&\*\#\@\!\%\+\=\_\-\:\;\'\"\,\.]/, "gi"),
- // remove words like "official video", "official audio", "official music video"
- new RegExp(/official\s(video|audio|music\svideo)/, "gi"),
-]
-
-export default async ({
- title,
- artist,
- sessionToken,
-} = {}) => {
- let query = `${title} artist:${artist}`
-
- // run clear query regexs
- for (const regex of clearQueryRegexs) {
- query = query.replace(regex, "")
- }
-
- const { data } = await global.comty.instances.default({
- method: "GET",
- headers: {
- "Authorization": `Bearer ${sessionToken}`,
- },
- params: {
- query: query,
- type: "track",
- },
- url: "/sync/spotify/search",
- }).catch((error) => {
- console.error(error.response.data)
-
- return null
- })
-
- if (!data) {
- return null
- }
-
- return data.tracks.items[0].id
-}
\ No newline at end of file
diff --git a/packages/server/services/music/services/getEnhancedLyricsFromTrack.js b/packages/server/services/music/services/getEnhancedLyricsFromTrack.js
deleted file mode 100755
index 722e7bbc..00000000
--- a/packages/server/services/music/services/getEnhancedLyricsFromTrack.js
+++ /dev/null
@@ -1,73 +0,0 @@
-import findSpotifyId from "@services/findSpotifyId"
-import { Track } from "@db_models"
-import axios from "axios"
-
-const syncLyricsProvider = process.env.LYRICS_SYNC_PROVIDER || `https://spotify-lyric-api.herokuapp.com`
-const canvasProvider = process.env.LYRICS_CANVAS_PROVIDER || `https://c_cdn-test.ragestudio.net/api/canvas`
-
-export default async (track, { req }) => {
- if (typeof track !== "object") {
- throw new Error("Track must be an object")
- }
-
- if (!track._id) {
- throw new Error("Track must have an _id")
- }
-
- if (!track.lyricsEnabled) {
- throw new Error("Track lyrics are not enabled")
- }
-
- let lyricData = {
- syncType: null,
- lines: null,
- canvas_url: null,
- }
-
- if (!track.spotifyId) {
- if (!req.session) {
- throw new Error("Session not found and track has no spotify id")
- }
-
- const spotifyId = await findSpotifyId({
- title: track.title,
- artist: track.artist,
- sessionToken: req.sessionToken,
- }, { req })
-
- if (!spotifyId) {
- throw new Error("Track has no spotify id")
- }
-
- track.spotifyId = spotifyId
-
- await Track.findOneAndUpdate({
- _id: track._id.toString(),
- }, { spotifyId })
- }
-
- let { data } = await axios.get(`${syncLyricsProvider}/?trackid=${track.spotifyId}`)
-
- lyricData.syncType = data.syncType
- lyricData.lines = data.lines
-
- if (track.videoCanvas) {
- lyricData.canvas_url = track.videoCanvas
- } else {
- try {
- const { data } = await axios.get(`${canvasProvider}/${track.spotifyId}`)
-
- lyricData.canvas_url = data.canvas_url
-
- await Track.findOneAndUpdate({
- _id: track._id.toString(),
- }, {
- videoCanvas: data.canvas_url,
- })
- } catch (err) {
- //console.log(err.response.data)
- }
- }
-
- return lyricData
-}
\ No newline at end of file
diff --git a/packages/server/services/music/services/removeTracks.js b/packages/server/services/music/services/removeTracks.js
deleted file mode 100755
index eb79f4dd..00000000
--- a/packages/server/services/music/services/removeTracks.js
+++ /dev/null
@@ -1,49 +0,0 @@
-import { Track } from "@db_models"
-
-const urlRegex = new RegExp(`^https://(.*?)/(.*)$`)
-
-export default async (tracksIds) => {
- if (typeof tracksIds === "string") {
- tracksIds = [tracksIds]
- }
-
- const removedIds = []
-
- // find Tracks
- const tracks = await Track.find({
- _id: tracksIds,
- })
-
- for (const track of tracks) {
- const match = urlRegex.exec(track.source)
-
- const bucket = match[2].split("/")[0]
- const objectName = match[2].split("/").slice(1).join("/")
-
- try {
- // find on storage and remove
- await new Promise((resolve, reject) => {
- global.storage.removeObject(bucket, objectName, (err) => {
- if (err) {
- return reject(err)
- }
-
- return resolve()
- })
- }).catch((err) => {
- console.error(err)
- return false
- })
-
- // remove from db
- await track.remove()
- } catch (error) {
- console.error(error)
- continue
- }
-
- removedIds.push(track._id)
- }
-
- return removedIds
-}
\ No newline at end of file
diff --git a/packages/server/services/music/ws.js b/packages/server/services/music/ws.js
deleted file mode 100755
index 63aed8ae..00000000
--- a/packages/server/services/music/ws.js
+++ /dev/null
@@ -1,117 +0,0 @@
-import socketio from "socket.io"
-import generateFnHandler from "@utils/generateFnHandler"
-
-import withWsAuth from "@middlewares/withWsAuth"
-
-import RoomsController from "@classes/RoomsController"
-
-export default class WebsocketServer {
- constructor(server) {
- this.io = socketio(server, {
- cors: {
- origin: "*",
- methods: ["GET", "POST"],
- credentials: true,
- }
- })
-
- if (global.ioAdapter) {
- this.io.adapter(global.ioAdapter)
- }
-
- this.RoomsController = new RoomsController(this.io)
-
- return this
- }
-
- connectionPool = []
-
- events = {
-
- }
-
- inviteUserToRoom = async (socket, data) => {
- try {
- // find sockets with matching user_id
- const invitedSockets = this.connectionPool.filter((client) => client.userData._id === data.user_id)
-
- if (invitedSockets.length === 0) {
- console.warn(`[${socket.id}][@${socket.userData.username}] cannot invite user ${data.user_id}, user not found in connection pool`)
- return socket.emit("error", {
- message: `User ${data.user_id} not found`,
- })
- }
-
- for (const invitedSocket of invitedSockets) {
- // check if user is already connected to the room
- if (invitedSocket.connectedRoomId === data.roomId) {
- console.warn(`[${socket.id}][@${socket.userData.username}] cannot invite user ${data.user_id}, user already connected to room ${data.roomId}`)
- return false
- }
-
- console.log(`[${socket.id}][@${socket.userData.username}] inviting user ${data.user_id} to room ${data.roomId}`)
-
- invitedSocket.emit("invite:received", {
- roomId: data.roomId,
- invitedBy: {
- _id: socket.userData._id,
- username: socket.userData.username,
- fullName: socket.userData.fullName,
- avatar: socket.userData.avatar,
- },
- })
- }
- } catch (error) {
- return socket.emit("error", {
- message: error.message,
- })
- }
- }
-
- initialize = async () => {
- this.io.use(withWsAuth)
-
- this.io.on("connection", (socket) => {
- try {
- console.log(`[${socket.id}][${socket.userData.username}] connected to hub.`)
-
- this.connectionPool.push(socket)
-
- socket.on("disconnect", () => this.events.disconnect)
-
- // Rooms
- socket.on("join:room", (data) => this.RoomsController.connectSocketToRoom(socket, data.room, data.options))
- socket.on("leave:room", (data) => this.RoomsController.disconnectSocketFromRoom(socket, data?.room ?? socket.connectedRoomId, data?.options ?? {}))
- socket.on("invite:user", generateFnHandler(this.inviteUserToRoom, socket))
-
- socket.on("ping", (callback) => {
- callback()
- })
-
- socket.on("disconnect", (_socket) => {
- console.log(`[${socket.id}][@${socket.userData.username}] disconnected to hub.`)
-
- if (socket.connectedRoomId) {
- console.log(`[${socket.id}][@${socket.userData.username}] was connected to room [${socket.connectedRoomId}], leaving...`)
- this.RoomsController.disconnectSocketFromRoom(socket)
- }
-
- // remove from connection pool
- this.connectionPool = this.connectionPool.filter((client) => client.id !== socket.id)
- })
-
- Object.entries(this.events).forEach(([event, handler]) => {
- socket.on(event, (data) => {
- try {
- handler(socket, data)
- } catch (error) {
- console.error(error)
- }
- })
- })
- } catch (error) {
- console.error(error)
- }
- })
- }
-}
diff --git a/packages/server/services/notifications/notifications.service.js b/packages/server/services/notifications/notifications.service.js
index beb2cfe8..f62aeb40 100644
--- a/packages/server/services/notifications/notifications.service.js
+++ b/packages/server/services/notifications/notifications.service.js
@@ -1,4 +1,4 @@
-import { Server } from "linebridge/src/server"
+import { Server } from "linebridge/dist/server"
import DbManager from "@shared-classes/DbManager"
import RedisClient from "@shared-classes/RedisClient"
diff --git a/packages/server/services/notifications/package.json b/packages/server/services/notifications/package.json
index bcd2c871..b4692cff 100644
--- a/packages/server/services/notifications/package.json
+++ b/packages/server/services/notifications/package.json
@@ -1,6 +1,4 @@
{
"name": "notifications",
- "version": "1.0.0",
- "main": "index.js",
- "license": "MIT"
+ "version": "1.0.0"
}
diff --git a/packages/server/services/posts/classes/posts/methods/fullfill.js b/packages/server/services/posts/classes/posts/methods/fullfill.js
index 3345b529..a75532ac 100644
--- a/packages/server/services/posts/classes/posts/methods/fullfill.js
+++ b/packages/server/services/posts/classes/posts/methods/fullfill.js
@@ -73,7 +73,7 @@ export default async (payload = {}) => {
}
}
- post.hasReplies = await Post.count({ reply_to: post._id })
+ post.hasReplies = await Post.countDocuments({ reply_to: post._id })
let likes = likesData[post._id.toString()] ?? []
diff --git a/packages/server/services/posts/classes/posts/methods/toggleLike.js b/packages/server/services/posts/classes/posts/methods/toggleLike.js
index 8262c8a7..9a0a3661 100644
--- a/packages/server/services/posts/classes/posts/methods/toggleLike.js
+++ b/packages/server/services/posts/classes/posts/methods/toggleLike.js
@@ -40,7 +40,7 @@ export default async (payload = {}) => {
await PostLike.findByIdAndDelete(likeObj._id)
}
- const count = await PostLike.count({
+ const count = await PostLike.countDocuments({
post_id,
})
diff --git a/packages/server/services/posts/package.json b/packages/server/services/posts/package.json
index e76389ea..56952f06 100644
--- a/packages/server/services/posts/package.json
+++ b/packages/server/services/posts/package.json
@@ -1,12 +1,6 @@
{
"name": "posts",
"version": "1.0.0",
- "main": "index.js",
- "license": "MIT",
- "proxy": {
- "namespace": "/posts",
- "port": 3001
- },
"dependencies": {
"moment-timezone": "^0.5.45"
}
diff --git a/packages/server/services/posts/posts.service.js b/packages/server/services/posts/posts.service.js
index ffe79cb8..7db00306 100644
--- a/packages/server/services/posts/posts.service.js
+++ b/packages/server/services/posts/posts.service.js
@@ -1,4 +1,4 @@
-import { Server } from "linebridge/src/server"
+import { Server } from "linebridge/dist/server"
import DbManager from "@shared-classes/DbManager"
import RedisClient from "@shared-classes/RedisClient"
diff --git a/packages/server/services/sync/classes/VRCApi/index.js b/packages/server/services/sync/classes/VRCApi/index.js
deleted file mode 100755
index 6e66ad30..00000000
--- a/packages/server/services/sync/classes/VRCApi/index.js
+++ /dev/null
@@ -1,59 +0,0 @@
-import axios from "axios"
-
-export default class VRCApi {
- static base_api_hostname = "https://api.vrchat.cloud/api/1"
-
- static get interface() {
- return axios.create({
- baseURL: VRCApi.base_api_hostname,
- headers: {
- "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.142.86 Safari/537.36",
- }
- })
- }
-
- static async auth({ username, password }, access_token) {
- username = encodeURIComponent(username)
- password = encodeURIComponent(password)
-
- let headers = {
- "Authorization": `Basic ${Buffer.from(`${username}:${password}`).toString("base64")}`
- }
-
- if (access_token) {
- delete headers["Authorization"]
- headers["Cookie"] = `${access_token}`
- }
-
- const response = await VRCApi.interface({
- method: "GET",
- url: "/auth/user",
- headers,
- })
-
- if (!access_token && response.headers["set-cookie"]) {
- response.data.cookie = response.headers["set-cookie"][0].split(";")[0]
- }
-
- return response.data
- }
-
- static async verifyOtp({ type, code }, access_token) {
- const response = await VRCApi.interface({
- method: "POST",
- url: `/auth/twofactorauth/${type}/verify`,
- data: {
- code: code
- },
- headers: {
- "Cookie": `${access_token}`
- },
- })
-
- if (!access_token && response.headers["set-cookie"]) {
- response.data.cookie = response.headers["set-cookie"][0].split(";")[0]
- }
-
- return response.data
- }
-}
\ No newline at end of file
diff --git a/packages/server/services/sync/controllers/main/index.js b/packages/server/services/sync/controllers/main/index.js
deleted file mode 100755
index 6ce9343e..00000000
--- a/packages/server/services/sync/controllers/main/index.js
+++ /dev/null
@@ -1,11 +0,0 @@
-import path from "path"
-import createRoutesFromDirectory from "@utils/createRoutesFromDirectory"
-
-export default async (router) => {
- router = createRoutesFromDirectory("routes", path.resolve(__dirname, "routes"), router)
-
- return {
- path: "/",
- router,
- }
-}
\ No newline at end of file
diff --git a/packages/server/services/sync/controllers/main/routes/get/active_services.js b/packages/server/services/sync/controllers/main/routes/get/active_services.js
deleted file mode 100755
index 6c65a9f3..00000000
--- a/packages/server/services/sync/controllers/main/routes/get/active_services.js
+++ /dev/null
@@ -1,32 +0,0 @@
-import SecureSyncEntry from "@shared-classes/SecureSyncEntry"
-import { AuthorizationError } from "@shared-classes/Errors"
-
-export default async (req, res) => {
- if (!req.session) {
- return new AuthorizationError(req, res)
- }
-
- let access = {}
-
- const check_map = [
- ["vrc", async () => await SecureSyncEntry.has(req.session.user_id.toString(), "vrc_access_token")],
- ["tidal", async () => await SecureSyncEntry.has(req.session.user_id.toString(), "tidal_access_token")],
- ["spotify", async () => await SecureSyncEntry.has(req.session.user_id.toString(), "spotify_access_token")],
- ]
-
- try {
- for (const check of check_map) {
- const [service, fn] = check
-
- if (await fn()) {
- access[service] = true
- } else {
- access[service] = false
- }
- }
- } catch (error) {
- return res.status(500).json({ error: error.message })
- }
-
- return res.json(access)
-}
\ No newline at end of file
diff --git a/packages/server/services/sync/controllers/services/index.js b/packages/server/services/sync/controllers/services/index.js
deleted file mode 100755
index e30b2052..00000000
--- a/packages/server/services/sync/controllers/services/index.js
+++ /dev/null
@@ -1,11 +0,0 @@
-import path from "path"
-import createRoutesFromDirectory from "@utils/createRoutesFromDirectory"
-
-export default async (router) => {
- router = createRoutesFromDirectory("routes", path.resolve(__dirname, "routes"), router)
-
- return {
- path: "/services",
- router,
- }
-}
\ No newline at end of file
diff --git a/packages/server/services/sync/controllers/services/routes/delete/tidal/track/[track_id]/like.js b/packages/server/services/sync/controllers/services/routes/delete/tidal/track/[track_id]/like.js
deleted file mode 100755
index 1e33eb80..00000000
--- a/packages/server/services/sync/controllers/services/routes/delete/tidal/track/[track_id]/like.js
+++ /dev/null
@@ -1,34 +0,0 @@
-import SecureSyncEntry from "@shared-classes/SecureSyncEntry"
-import { AuthorizationError, InternalServerError } from "@shared-classes/Errors"
-
-import TidalAPI from "@shared-classes/TidalAPI"
-
-export default async (req, res) => {
- if (!req.session) {
- return new AuthorizationError(req, res)
- }
-
- try {
- const access_token = await SecureSyncEntry.get(req.session.user_id.toString(), "tidal_access_token")
-
- if (!access_token) {
- return new AuthorizationError(req, res, "Its needed to link your TIDAL account to perform this action.")
- }
-
- let user_data = await SecureSyncEntry.get(req.session.user_id.toString(), "tidal_user")
-
- user_data = JSON.parse(user_data)
-
- let response = await TidalAPI.toggleTrackLike({
- trackId: req.params.track_id,
- to: false,
- user_id: user_data.id,
- access_token,
- country: user_data.country,
- })
-
- return res.json(response)
- } catch (error) {
- return new InternalServerError(req, res, error)
- }
-}
diff --git a/packages/server/services/sync/controllers/services/routes/get/tidal/create_link.js b/packages/server/services/sync/controllers/services/routes/get/tidal/create_link.js
deleted file mode 100755
index b5de570a..00000000
--- a/packages/server/services/sync/controllers/services/routes/get/tidal/create_link.js
+++ /dev/null
@@ -1,47 +0,0 @@
-import SecureSyncEntry from "@shared-classes/SecureSyncEntry"
-import { AuthorizationError, InternalServerError } from "@shared-classes/Errors"
-
-import TidalAPI from "@shared-classes/TidalAPI"
-
-export default async (req, res) => {
- if (!req.session) {
- return new AuthorizationError(req, res)
- }
-
- const authProcess = await TidalAPI.getAuthUrl()
-
- if (!authProcess) {
- return new InternalServerError(req, res)
- }
-
- const checkInterval = setInterval(async () => {
- const response = await TidalAPI.checkAuthStatus(authProcess.device_code).catch(() => {
- return false
- })
-
- if (response) {
- const userData = {
- id: response.user.userId,
- email: response.user.email,
- username: response.user.username,
- countryCode: response.user.countryCode,
- }
-
- // save to SecureSyncEntry
- await SecureSyncEntry.set(req.session.user_id.toString(), "tidal_user", JSON.stringify(userData))
- await SecureSyncEntry.set(req.session.user_id.toString(), "tidal_access_token", response.access_token)
- await SecureSyncEntry.set(req.session.user_id.toString(), "tidal_refresh_token", response.refresh_token)
-
- return clearInterval(checkInterval)
- }
- }, 3000)
-
- setTimeout(() => {
- clearInterval(checkInterval)
- }, authProcess.expires_in * 1000)
-
- return res.json({
- auth_url: authProcess.url,
- device_code: authProcess.deviceCode,
- })
-}
\ No newline at end of file
diff --git a/packages/server/services/sync/controllers/services/routes/get/tidal/current.js b/packages/server/services/sync/controllers/services/routes/get/tidal/current.js
deleted file mode 100755
index 7143396d..00000000
--- a/packages/server/services/sync/controllers/services/routes/get/tidal/current.js
+++ /dev/null
@@ -1,22 +0,0 @@
-import SecureSyncEntry from "@shared-classes/SecureSyncEntry"
-import { AuthorizationError, InternalServerError, NotFoundError } from "@shared-classes/Errors"
-
-export default async (req, res) => {
- if (!req.session) {
- return new AuthorizationError(req, res)
- }
-
- let user = await SecureSyncEntry.get(req.session.user_id.toString(), "tidal_user")
-
- try {
- user = JSON.parse(user)
-
- if (!user) {
- return new NotFoundError(req, res)
- }
-
- return res.json(user)
- } catch (error) {
- return new InternalServerError(req, res)
- }
-}
\ No newline at end of file
diff --git a/packages/server/services/sync/controllers/services/routes/get/tidal/favorites/playlists.js b/packages/server/services/sync/controllers/services/routes/get/tidal/favorites/playlists.js
deleted file mode 100755
index 60c924bb..00000000
--- a/packages/server/services/sync/controllers/services/routes/get/tidal/favorites/playlists.js
+++ /dev/null
@@ -1,34 +0,0 @@
-import SecureSyncEntry from "@shared-classes/SecureSyncEntry"
-import { AuthorizationError, InternalServerError, NotFoundError } from "@shared-classes/Errors"
-
-import TidalAPI from "@shared-classes/TidalAPI"
-
-export default async (req, res) => {
- if (!req.session) {
- return new AuthorizationError(req, res)
- }
-
- try {
- const access_token = await SecureSyncEntry.get(req.session.user_id.toString(), "tidal_access_token")
-
- if (!access_token) {
- return new AuthorizationError(req, res, "Its needed to link your TIDAL account to perform this action.")
- }
-
- let user_data = await SecureSyncEntry.get(req.session.user_id.toString(), "tidal_user")
-
- user_data = JSON.parse(user_data)
-
- let response = await TidalAPI.getFavoritePlaylists({
- user_id: user_data.id,
- country: user_data.countryCode,
- access_token: access_token,
- limit: Number(req.query.limit ?? 50),
- offset: Number(req.query.offset ?? 0),
- })
-
- return res.json(response)
- } catch (error) {
- return new InternalServerError(req, res, error)
- }
-}
diff --git a/packages/server/services/sync/controllers/services/routes/get/tidal/favorites/tracks.js b/packages/server/services/sync/controllers/services/routes/get/tidal/favorites/tracks.js
deleted file mode 100755
index b1925878..00000000
--- a/packages/server/services/sync/controllers/services/routes/get/tidal/favorites/tracks.js
+++ /dev/null
@@ -1,34 +0,0 @@
-import SecureSyncEntry from "@shared-classes/SecureSyncEntry"
-import { AuthorizationError, InternalServerError, NotFoundError } from "@shared-classes/Errors"
-
-import TidalAPI from "@shared-classes/TidalAPI"
-
-export default async (req, res) => {
- if (!req.session) {
- return new AuthorizationError(req, res)
- }
-
- try {
- const access_token = await SecureSyncEntry.get(req.session.user_id.toString(), "tidal_access_token")
-
- if (!access_token) {
- return new AuthorizationError(req, res, "Its needed to link your TIDAL account to perform this action.")
- }
-
- let user_data = await SecureSyncEntry.get(req.session.user_id.toString(), "tidal_user")
-
- user_data = JSON.parse(user_data)
-
- const response = await TidalAPI.getFavoriteTracks({
- user_id: user_data.id,
- country: user_data.countryCode,
- access_token: access_token,
- limit: Number(req.query.limit ?? 50),
- offset: Number(req.query.offset ?? 0),
- })
-
- return res.json(response)
- } catch (error) {
- return new InternalServerError(req, res, error)
- }
-}
\ No newline at end of file
diff --git a/packages/server/services/sync/controllers/services/routes/get/tidal/is_active.js b/packages/server/services/sync/controllers/services/routes/get/tidal/is_active.js
deleted file mode 100755
index 13407d79..00000000
--- a/packages/server/services/sync/controllers/services/routes/get/tidal/is_active.js
+++ /dev/null
@@ -1,18 +0,0 @@
-import SecureSyncEntry from "@shared-classes/SecureSyncEntry"
-import { AuthorizationError, NotFoundError } from "@shared-classes/Errors"
-
-export default async (req, res) => {
- if (!req.session) {
- return new AuthorizationError(req, res)
- }
-
- let hasUser = await SecureSyncEntry.has(req.session.user_id.toString(), "tidal_user")
-
- if (!hasUser) {
- return new NotFoundError(req, res, "This account is not linked to a TIDAL account.")
- }
-
- return res.json({
- active: hasUser
- })
-}
\ No newline at end of file
diff --git a/packages/server/services/sync/controllers/services/routes/get/tidal/manifest/[track_id].js b/packages/server/services/sync/controllers/services/routes/get/tidal/manifest/[track_id].js
deleted file mode 100755
index 9756c003..00000000
--- a/packages/server/services/sync/controllers/services/routes/get/tidal/manifest/[track_id].js
+++ /dev/null
@@ -1,36 +0,0 @@
-import SecureSyncEntry from "@shared-classes/SecureSyncEntry"
-import { AuthorizationError, InternalServerError, NotFoundError } from "@shared-classes/Errors"
-
-import TidalAPI from "@shared-classes/TidalAPI"
-
-export default async (req, res) => {
- if (!req.session) {
- return new AuthorizationError(req, res)
- }
-
- try {
- const access_token = await SecureSyncEntry.get(req.session.user_id.toString(), "tidal_access_token")
-
- if (!access_token) {
- return new AuthorizationError(req, res, "Its needed to link your TIDAL account to perform this action.")
- }
-
- let user_data = await SecureSyncEntry.get(req.session.user_id.toString(), "tidal_user")
-
- user_data = JSON.parse(user_data)
-
- const response = await TidalAPI.getTrackManifest({
- track_id: req.params.track_id,
- access_token: access_token,
- country: user_data.countryCode
- })
-
- if (!response) {
- return new NotFoundError(req, res, "Track is not available")
- }
-
- return res.json(response)
- } catch (error) {
- return new InternalServerError(req, res, error)
- }
-}
\ No newline at end of file
diff --git a/packages/server/services/sync/controllers/services/routes/get/tidal/playback/[track_id].js b/packages/server/services/sync/controllers/services/routes/get/tidal/playback/[track_id].js
deleted file mode 100755
index e801ebec..00000000
--- a/packages/server/services/sync/controllers/services/routes/get/tidal/playback/[track_id].js
+++ /dev/null
@@ -1,27 +0,0 @@
-import SecureSyncEntry from "@shared-classes/SecureSyncEntry"
-import { AuthorizationError, InternalServerError, NotFoundError } from "@shared-classes/Errors"
-
-import TidalAPI from "@shared-classes/TidalAPI"
-
-export default async (req, res) => {
- if (!req.session) {
- return new AuthorizationError(req, res)
- }
-
- const access_token = await SecureSyncEntry.get(req.session.user_id.toString(), "tidal_access_token")
-
- if (!access_token) {
- return new AuthorizationError(req, res, "Its needed to link your TIDAL account to perform this action.")
- }
-
- const response = await TidalAPI.getTrackPlaybackUrl({
- track_id: req.params.track_id,
- access_token: access_token
- })
-
- if (!response) {
- return new NotFoundError(req, res, "Track is not available")
- }
-
- return res.json(response)
-}
\ No newline at end of file
diff --git a/packages/server/services/sync/controllers/services/routes/get/tidal/playlist/[uuid]/data.js b/packages/server/services/sync/controllers/services/routes/get/tidal/playlist/[uuid]/data.js
deleted file mode 100755
index 01612465..00000000
--- a/packages/server/services/sync/controllers/services/routes/get/tidal/playlist/[uuid]/data.js
+++ /dev/null
@@ -1,35 +0,0 @@
-import SecureSyncEntry from "@shared-classes/SecureSyncEntry"
-import { AuthorizationError, InternalServerError, NotFoundError } from "@shared-classes/Errors"
-
-import TidalAPI from "@shared-classes/TidalAPI"
-
-export default async (req, res) => {
- if (!req.session) {
- return new AuthorizationError(req, res)
- }
-
- try {
- const access_token = await SecureSyncEntry.get(req.session.user_id.toString(), "tidal_access_token")
-
- if (!access_token) {
- return new AuthorizationError(req, res, "Its needed to link your TIDAL account to perform this action.")
- }
-
- let user_data = await SecureSyncEntry.get(req.session.user_id.toString(), "tidal_user")
-
- user_data = JSON.parse(user_data)
-
- let response = await TidalAPI.getPlaylistData({
- uuid: req.params.uuid,
- country: user_data.countryCode,
- access_token: access_token,
- limit: Number(req.query.limit ?? 50),
- offset: Number(req.query.offset ?? 0),
- resolve_items: req.query.resolve_items === "true",
- })
-
- return res.json(response)
- } catch (error) {
- return new InternalServerError(req, res, error)
- }
-}
diff --git a/packages/server/services/sync/controllers/services/routes/get/tidal/playlist/[uuid]/items.js b/packages/server/services/sync/controllers/services/routes/get/tidal/playlist/[uuid]/items.js
deleted file mode 100755
index 61a90e47..00000000
--- a/packages/server/services/sync/controllers/services/routes/get/tidal/playlist/[uuid]/items.js
+++ /dev/null
@@ -1,34 +0,0 @@
-import SecureSyncEntry from "@shared-classes/SecureSyncEntry"
-import { AuthorizationError, InternalServerError, NotFoundError } from "@shared-classes/Errors"
-
-import TidalAPI from "@shared-classes/TidalAPI"
-
-export default async (req, res) => {
- if (!req.session) {
- return new AuthorizationError(req, res)
- }
-
- try {
- const access_token = await SecureSyncEntry.get(req.session.user_id.toString(), "tidal_access_token")
-
- if (!access_token) {
- return new AuthorizationError(req, res, "Its needed to link your TIDAL account to perform this action.")
- }
-
- let user_data = await SecureSyncEntry.get(req.session.user_id.toString(), "tidal_user")
-
- user_data = JSON.parse(user_data)
-
- let response = await TidalAPI.getPlaylistItems({
- uuid: req.params.uuid,
- country: user_data.countryCode,
- access_token: access_token,
- limit: Number(req.query.limit ?? 50),
- offset: Number(req.query.offset ?? 0),
- })
-
- return res.json(response)
- } catch (error) {
- return new InternalServerError(req, res, error)
- }
-}
diff --git a/packages/server/services/sync/controllers/services/routes/get/tidal/search.js b/packages/server/services/sync/controllers/services/routes/get/tidal/search.js
deleted file mode 100755
index 3dd115a4..00000000
--- a/packages/server/services/sync/controllers/services/routes/get/tidal/search.js
+++ /dev/null
@@ -1,11 +0,0 @@
-import TidalAPI from "@shared-classes/TidalAPI"
-
-export default async (req, res) => {
- const query = req.query
-
- const response = await TidalAPI.search({
- query: query.query
- })
-
- return res.json(response)
-}
\ No newline at end of file
diff --git a/packages/server/services/sync/controllers/services/routes/get/vrc/session.js b/packages/server/services/sync/controllers/services/routes/get/vrc/session.js
deleted file mode 100755
index feb561e3..00000000
--- a/packages/server/services/sync/controllers/services/routes/get/vrc/session.js
+++ /dev/null
@@ -1,12 +0,0 @@
-import SecureSyncEntry from "@shared-classes/SecureSyncEntry"
-import { AuthorizationError } from "@shared-classes/Errors"
-
-export default async (req, res) => {
- if (!req.session) {
- return new AuthorizationError(req, res)
- }
-
- const userData = await SecureSyncEntry.get(req.session.user_id.toString(), "vrc:user_data")
-
- return res.json(JSON.parse(userData))
-}
\ No newline at end of file
diff --git a/packages/server/services/sync/controllers/services/routes/post/tidal/delete_link.js b/packages/server/services/sync/controllers/services/routes/post/tidal/delete_link.js
deleted file mode 100755
index 6b62f093..00000000
--- a/packages/server/services/sync/controllers/services/routes/post/tidal/delete_link.js
+++ /dev/null
@@ -1,16 +0,0 @@
-import SecureSyncEntry from "@shared-classes/SecureSyncEntry"
-import { AuthorizationError, InternalServerError } from "@shared-classes/Errors"
-
-export default async (req, res) => {
- if (!req.session) {
- return new AuthorizationError(req, res)
- }
-
- await SecureSyncEntry.delete(req.session.user_id.toString(), "tidal_user")
- await SecureSyncEntry.delete(req.session.user_id.toString(), "tidal_access_token")
- await SecureSyncEntry.delete(req.session.user_id.toString(), "tidal_refresh_token")
-
- return res.json({
- success: true
- })
-}
\ No newline at end of file
diff --git a/packages/server/services/sync/controllers/services/routes/post/tidal/track/[track_id]/like.js b/packages/server/services/sync/controllers/services/routes/post/tidal/track/[track_id]/like.js
deleted file mode 100755
index 7993508a..00000000
--- a/packages/server/services/sync/controllers/services/routes/post/tidal/track/[track_id]/like.js
+++ /dev/null
@@ -1,35 +0,0 @@
-import SecureSyncEntry from "@shared-classes/SecureSyncEntry"
-import { AuthorizationError, InternalServerError } from "@shared-classes/Errors"
-
-import TidalAPI from "@shared-classes/TidalAPI"
-
-export default async (req, res) => {
- if (!req.session) {
- return new AuthorizationError(req, res)
- }
-
- try {
- const access_token = await SecureSyncEntry.get(req.session.user_id.toString(), "tidal_access_token")
-
- if (!access_token) {
- return new AuthorizationError(req, res, "Its needed to link your TIDAL account to perform this action.")
- }
-
- let user_data = await SecureSyncEntry.get(req.session.user_id.toString(), "tidal_user")
-
- user_data = JSON.parse(user_data)
-
- let response = await TidalAPI.toggleTrackLike({
- trackId: req.params.track_id,
- to: true,
- user_id: user_data.id,
- access_token,
- country: user_data.countryCode,
- })
-
- return res.json(response)
- } catch (error) {
- console.error(error)
- return new InternalServerError(req, res, error)
- }
-}
diff --git a/packages/server/services/sync/controllers/services/routes/post/vrc/auth.js b/packages/server/services/sync/controllers/services/routes/post/vrc/auth.js
deleted file mode 100755
index 1a1f1a8b..00000000
--- a/packages/server/services/sync/controllers/services/routes/post/vrc/auth.js
+++ /dev/null
@@ -1,57 +0,0 @@
-import SecureSyncEntry from "@shared-classes/SecureSyncEntry"
-import { AuthorizationError } from "@shared-classes/Errors"
-
-import ExternalAPI from "@classes/VRCApi"
-
-export default async (req, res) => {
- if (!req.session) {
- return new AuthorizationError(req, res)
- }
-
- req.body = await req.json()
-
- if (!req.body.username || !req.body.password) {
- return res.status(400).json({
- success: false,
- error: "Missing username or password",
- })
- }
-
- const currentAccessToken = await SecureSyncEntry.get(req.session.user_id.toString(), "vrc:access_token")
-
- const result = await ExternalAPI.auth({
- username: req.body.username,
- password: req.body.password
- }, currentAccessToken).catch((error) => {
- if (error.response) {
- console.error(error.response.data)
-
- res.status(500).json(error.response.data.error)
- } else {
- res.status(500).json({
- error: "Something went wrong",
- })
- }
-
- return null
- })
-
- if (!result) {
- return false
- }
-
- console.log(result)
-
- if (result.cookie) {
- await SecureSyncEntry.set(req.session.user_id.toString(), "vrc:access_token", cookie)
- }
-
- if (!result.requiresTwoFactorAuth) {
- await SecureSyncEntry.set(req.session.user_id.toString(), "vrc:user_data", JSON.stringify(result))
- }
-
- return res.json({
- success: result.requiresTwoFactorAuth ? true : false,
- ...result
- })
-}
\ No newline at end of file
diff --git a/packages/server/services/sync/controllers/services/routes/post/vrc/logout.js b/packages/server/services/sync/controllers/services/routes/post/vrc/logout.js
deleted file mode 100755
index e69de29b..00000000
diff --git a/packages/server/services/sync/controllers/services/routes/post/vrc/otp.js b/packages/server/services/sync/controllers/services/routes/post/vrc/otp.js
deleted file mode 100755
index e9e24c82..00000000
--- a/packages/server/services/sync/controllers/services/routes/post/vrc/otp.js
+++ /dev/null
@@ -1,45 +0,0 @@
-import SecureSyncEntry from "@shared-classes/SecureSyncEntry"
-import { AuthorizationError } from "@shared-classes/Errors"
-
-import ExternalAPI from "@classes/VRCApi"
-
-export default async (req, res) => {
- if (!req.session) {
- return new AuthorizationError(req, res)
- }
-
- req.body = await req.json()
-
- const { type, code } = req.body
-
- if (!type || !code) {
- return res.status(400).json({
- success: false,
- error: "Missing type or code",
- })
- }
-
- const authcookie = await SecureSyncEntry.get(req.session.user_id.toString(), "vrc:access_token")
-
- const result = await ExternalAPI.verifyOtp({ type, code }, authcookie).catch((error) => {
- if (error.response) {
- console.error(error.response.data)
-
- res.status(500).json(error.response.data.error)
- } else {
- console.error(error)
-
- res.status(500).json({
- error: "Something went wrong",
- })
- }
-
- return null
- })
-
- if (!result) {
- return false
- }
-
- return res.json(result)
-}
\ No newline at end of file
diff --git a/packages/server/services/sync/middlewares/withAuth/index.js b/packages/server/services/sync/middlewares/withAuth/index.js
deleted file mode 100755
index 52a30f4a..00000000
--- a/packages/server/services/sync/middlewares/withAuth/index.js
+++ /dev/null
@@ -1,25 +0,0 @@
-export default async function (req, res, next) {
- // extract authentification header
- let auth = req.headers.authorization
-
- if (!auth) {
- return res.status(401).json({ error: "Unauthorized, missing token" })
- }
-
- auth = auth.replace("Bearer ", "")
-
- // check if authentification is valid
- const validation = await comty.rest.session.validateToken(auth).catch((error) => {
- return {
- valid: false,
- }
- })
-
- if (!validation.valid) {
- return res.status(401).json({ error: "Unauthorized" })
- }
-
- req.session = validation.data
-
- return next()
-}
\ No newline at end of file
diff --git a/packages/server/services/sync/middlewares/withOptionalAuth/index.js b/packages/server/services/sync/middlewares/withOptionalAuth/index.js
deleted file mode 100755
index 9689973d..00000000
--- a/packages/server/services/sync/middlewares/withOptionalAuth/index.js
+++ /dev/null
@@ -1,26 +0,0 @@
-export default async function (req, res, next) {
- // extract authentification header
- let auth = req.headers.authorization
-
- if (!auth) {
- return next()
- }
-
- auth = auth.replace("Bearer ", "")
-
- // check if authentification is valid
- const validation = await comty.rest.session.validateToken(auth).catch((error) => {
- return {
- valid: false,
- }
- })
-
- if (!validation.valid) {
- return next()
- }
-
- req.sessionToken = auth
- req.session = validation.data
-
- return next()
-}
\ No newline at end of file
diff --git a/packages/server/services/sync/middlewares/withWsAuth.js b/packages/server/services/sync/middlewares/withWsAuth.js
deleted file mode 100755
index 31fed9d9..00000000
--- a/packages/server/services/sync/middlewares/withWsAuth.js
+++ /dev/null
@@ -1,55 +0,0 @@
-export default async (socket, next) => {
- try {
- const token = socket.handshake.auth.token
-
- if (!token) {
- return next(new Error(`auth:token_missing`))
- }
-
- const validation = await global.comty.rest.session.validateToken(token).catch((err) => {
- console.error(`[${socket.id}] failed to validate session caused by server error`, err)
-
- return {
- valid: false,
- error: err,
- }
- })
-
- if (!validation.valid) {
- if (validation.error) {
- return next(new Error(`auth:server_error`))
- }
-
- return next(new Error(`auth:token_invalid`))
- }
-
- const session = validation.data
-
- const userData = await global.comty.rest.user.data({
- user_id: session.user_id,
- }).catch((err) => {
- console.error(`[${socket.id}] failed to get user data caused by server error`, err)
-
- return null
- })
-
- if (!userData) {
- return next(new Error(`auth:user_failed`))
- }
-
- try {
- socket.userData = userData
- socket.token = token
- socket.session = session
- }
- catch (err) {
- return next(new Error(`auth:decode_failed`))
- }
-
- next()
- } catch (error) {
- console.error(`[${socket.id}] failed to connect caused by server error`, error)
-
- next(new Error(`auth:authentification_failed`))
- }
-}
\ No newline at end of file
diff --git a/packages/server/services/sync/package.json b/packages/server/services/sync/package.json
deleted file mode 100755
index a0d8962a..00000000
--- a/packages/server/services/sync/package.json
+++ /dev/null
@@ -1,25 +0,0 @@
-{
- "name": "sync",
- "version": "0.60.2",
- "license": "MIT",
- "dependencies": {
- "@foxify/events": "^2.1.0",
- "axios": "^1.2.5",
- "bcrypt": "^5.1.0",
- "comty.js": "^0.58.2",
- "connect-mongo": "^4.6.0",
- "content-range": "^2.0.2",
- "dotenv": "^16.0.3",
- "file-api": "^0.10.4",
- "form-data": "^4.0.0",
- "hyper-express": "^6.5.9",
- "jsonwebtoken": "^9.0.0",
- "linebridge": "0.15.12",
- "luxon": "^3.2.1",
- "normalize-url": "^8.0.0",
- "p-map": "^6.0.0",
- "p-queue": "^7.3.4",
- "qs": "^6.11.2",
- "redis": "^4.6.6"
- }
-}
\ No newline at end of file
diff --git a/packages/server/services/sync/sync.service.js b/packages/server/services/sync/sync.service.js
deleted file mode 100755
index c1facbdc..00000000
--- a/packages/server/services/sync/sync.service.js
+++ /dev/null
@@ -1,144 +0,0 @@
-import fs from "fs"
-import path from "path"
-
-import DbManager from "@shared-classes/DbManager"
-import RedisClient from "@shared-classes/RedisClient"
-import ComtyClient from "@shared-classes/ComtyClient"
-
-import hyperexpress from "hyper-express"
-
-import pkg from "./package.json"
-
-export default class API {
- static useMiddlewaresOrder = ["useLogger", "useCors", "useAuth"]
-
- server = global.server = new hyperexpress.Server()
-
- listenIp = process.env.HTTP_LISTEN_IP ?? "0.0.0.0"
- listenPort = process.env.HTTP_LISTEN_PORT ?? 3006
-
- internalRouter = new hyperexpress.Router()
-
- db = new DbManager()
-
- ssePools = global.ssePools = {}
-
- comty = global.comty = ComtyClient({
- useWs: false,
- })
-
- redis = global.redis = RedisClient()
-
- async __registerControllers() {
- let controllersPath = fs.readdirSync(path.resolve(__dirname, "controllers"))
-
- for await (const controllerPath of controllersPath) {
- const controller = require(path.resolve(__dirname, "controllers", controllerPath)).default
-
- if (!controller) {
- console.error(`Controller ${controllerPath} not found.`)
-
- continue
- }
-
- const controllerRouter = new hyperexpress.Router()
-
- const controllerOutput = await controller(controllerRouter)
-
- if (!controllerOutput) {
- console.error(`Controller ${controllerPath} returning not valid handler.`)
-
- continue
- }
-
- this.internalRouter.use(controllerOutput.path ?? "/", controllerOutput.router)
-
- continue
- }
- }
-
- async __registerInternalMiddlewares() {
- let middlewaresPath = fs.readdirSync(path.resolve(__dirname, "useMiddlewares"))
-
- // sort middlewares
- middlewaresPath = middlewaresPath.sort((a, b) => {
- const aIndex = this.constructor.useMiddlewaresOrder.indexOf(a.replace(".js", ""))
- const bIndex = this.constructor.useMiddlewaresOrder.indexOf(b.replace(".js", ""))
-
- if (aIndex === -1) {
- return 1
- }
-
- if (bIndex === -1) {
- return -1
- }
-
- return aIndex - bIndex
- })
-
- for await (const middlewarePath of middlewaresPath) {
- const middleware = require(path.resolve(__dirname, "useMiddlewares", middlewarePath)).default
-
- if (!middleware) {
- console.error(`Middleware ${middlewarePath} not found.`)
-
- continue
- }
-
- this.server.use(middleware)
- }
- }
-
- __registerInternalRoutes() {
- this.server.get("/", (req, res) => {
- return res.status(200).json({
- name: pkg.name,
- version: pkg.version,
- routes: this.__getRegisteredRoutes()
- })
- })
-
- this.server.any("*", (req, res) => {
- return res.status(404).json({
- error: "Not found",
- })
- })
- }
-
- __getRegisteredRoutes() {
- return this.internalRouter.routes.map((route) => {
- return {
- method: route.method,
- path: route.pattern,
- }
- })
- }
-
- async initialize() {
- const startHrTime = process.hrtime()
-
- // initialize clients
- await this.db.initialize()
- await this.redis.initialize()
-
- // register controllers & middlewares
- await this.__registerInternalRoutes()
- await this.__registerControllers()
- await this.__registerInternalMiddlewares()
-
- // use internal router
- this.server.use(this.internalRouter)
-
- // start server
- await this.server.listen(this.listenPort, this.listenIp)
-
- // calculate elapsed time
- const elapsedHrTime = process.hrtime(startHrTime)
- const elapsedTimeInMs = elapsedHrTime[0] * 1000 + elapsedHrTime[1] / 1e6
-
- // log server started
- console.log(`🚀 Server started ready on \n\t - http://${this.listenIp}:${this.listenPort} \n\t - Tooks ${elapsedTimeInMs}ms`)
- }
-}
-
-Boot(API)
\ No newline at end of file
diff --git a/packages/server/services/sync/useMiddlewares/useAuth/index.js b/packages/server/services/sync/useMiddlewares/useAuth/index.js
deleted file mode 100755
index 4d5bece4..00000000
--- a/packages/server/services/sync/useMiddlewares/useAuth/index.js
+++ /dev/null
@@ -1,25 +0,0 @@
-export default async function (req, res, next) {
- // extract authentification header
- let auth = req.headers.authorization
-
- if (!auth) {
- return false
- }
-
- auth = auth.replace("Bearer ", "")
-
- // check if authentification is valid
- const validation = await comty.rest.session.validateToken(auth).catch((error) => {
- return {
- valid: false,
- }
- })
-
- if (!validation.valid) {
- return res.status(401).json({ error: "Unauthorized" })
- }
-
- req.session = validation.data
-
- return true
-}
\ No newline at end of file
diff --git a/packages/server/services/sync/useMiddlewares/useCors/index.js b/packages/server/services/sync/useMiddlewares/useCors/index.js
deleted file mode 100755
index 7ebac0fc..00000000
--- a/packages/server/services/sync/useMiddlewares/useCors/index.js
+++ /dev/null
@@ -1,8 +0,0 @@
-import cors from "cors"
-
-export default cors({
- origin: "*",
- methods: ["GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS", "HEAD", "CONNECT", "TRACE"],
- preflightContinue: false,
- optionsSuccessStatus: 204,
-})
\ No newline at end of file
diff --git a/packages/server/services/sync/useMiddlewares/useLogger/index.js b/packages/server/services/sync/useMiddlewares/useLogger/index.js
deleted file mode 100755
index 5e9c64f4..00000000
--- a/packages/server/services/sync/useMiddlewares/useLogger/index.js
+++ /dev/null
@@ -1,14 +0,0 @@
-export default (req, res, next) => {
- const startHrTime = process.hrtime()
-
- res.on("finish", () => {
- const elapsedHrTime = process.hrtime(startHrTime)
- const elapsedTimeInMs = elapsedHrTime[0] * 1000 + elapsedHrTime[1] / 1e6
-
- res._responseTimeMs = elapsedTimeInMs
-
- console.log(`${req.method} ${res._status_code ?? res.statusCode ?? 200} ${req.url} ${elapsedTimeInMs}ms`)
- })
-
- next()
-}
\ No newline at end of file
diff --git a/packages/server/services/sync/utils/composePayloadData/index.js b/packages/server/services/sync/utils/composePayloadData/index.js
deleted file mode 100755
index de5761f5..00000000
--- a/packages/server/services/sync/utils/composePayloadData/index.js
+++ /dev/null
@@ -1,12 +0,0 @@
-export default function composePayloadData(socket, data = {}) {
- return {
- user: {
- user_id: socket.userData._id,
- username: socket.userData.username,
- fullName: socket.userData.fullName,
- avatar: socket.userData.avatar,
- },
- command_issuer: data.command_issuer ?? socket.userData._id,
- ...data
- }
-}
\ No newline at end of file
diff --git a/packages/server/services/sync/utils/createRoutesFromDirectory/index.js b/packages/server/services/sync/utils/createRoutesFromDirectory/index.js
deleted file mode 100755
index f27647a0..00000000
--- a/packages/server/services/sync/utils/createRoutesFromDirectory/index.js
+++ /dev/null
@@ -1,45 +0,0 @@
-import fs from "fs"
-
-function createRoutesFromDirectory(startFrom, directoryPath, router) {
- const files = fs.readdirSync(directoryPath)
-
- files.forEach((file) => {
- const filePath = `${directoryPath}/${file}`
-
- const stat = fs.statSync(filePath)
-
- if (stat.isDirectory()) {
- createRoutesFromDirectory(startFrom, filePath, router)
- } else if (file.endsWith(".js") || file.endsWith(".jsx") || file.endsWith(".ts") || file.endsWith(".tsx")) {
- let splitedFilePath = filePath.split("/")
-
- // slice the startFrom path
- splitedFilePath = splitedFilePath.slice(splitedFilePath.indexOf(startFrom) + 1)
-
- const method = splitedFilePath[0]
-
- let route = splitedFilePath.slice(1, splitedFilePath.length).join("/")
-
- route = route.replace(".jsx", "")
- route = route.replace(".js", "")
- route = route.replace(".ts", "")
- route = route.replace(".tsx", "")
-
- if (route === "index") {
- route = "/"
- } else {
- route = `/${route}`
- }
-
- let handler = require(filePath)
-
- handler = handler.default || handler
-
- router[method](route, handler)
- }
- })
-
- return router
-}
-
-export default createRoutesFromDirectory
\ No newline at end of file
diff --git a/packages/server/services/sync/utils/generateFnHandler/index.js b/packages/server/services/sync/utils/generateFnHandler/index.js
deleted file mode 100755
index 4c5962d5..00000000
--- a/packages/server/services/sync/utils/generateFnHandler/index.js
+++ /dev/null
@@ -1,21 +0,0 @@
-export default function generateFnHandler(fn, socket) {
- return async (...args) => {
- if (typeof socket === "undefined") {
- socket = arguments[0]
- }
-
- try {
- fn(socket, ...args)
- } catch (error) {
- console.error(`[HANDLER_ERROR] ${error.message} >`, error.stack)
-
- if (typeof socket.emit !== "function") {
- return false
- }
-
- return socket.emit("error", {
- message: error.message,
- })
- }
- }
-}
\ No newline at end of file
diff --git a/packages/server/services/sync/utils/getMiddlewares/index.js b/packages/server/services/sync/utils/getMiddlewares/index.js
deleted file mode 100755
index 78a65ea0..00000000
--- a/packages/server/services/sync/utils/getMiddlewares/index.js
+++ /dev/null
@@ -1,46 +0,0 @@
-import fs from "node:fs"
-import path from "node:path"
-
-export default async (middlewares, middlewaresPath) => {
- if (typeof middlewaresPath === "undefined") {
- middlewaresPath = path.resolve(globalThis["__src"], "middlewares")
- }
-
- if (!fs.existsSync(middlewaresPath)) {
- return undefined
- }
-
- if (typeof middlewares === "string") {
- middlewares = [middlewares]
- }
-
- let fns = []
-
- for await (const middlewareName of middlewares) {
- const middlewarePath = path.resolve(middlewaresPath, middlewareName)
-
- if (!fs.existsSync(middlewarePath)) {
- console.error(`Middleware ${middlewareName} not found.`)
-
- continue
- }
-
- const middleware = require(middlewarePath).default
-
- if (!middleware) {
- console.error(`Middleware ${middlewareName} not valid export.`)
-
- continue
- }
-
- if (typeof middleware !== "function") {
- console.error(`Middleware ${middlewareName} not valid function.`)
-
- continue
- }
-
- fns.push(middleware)
- }
-
- return fns
-}
\ No newline at end of file
diff --git a/packages/server/services/sync/utils/resolveUrl/index.js b/packages/server/services/sync/utils/resolveUrl/index.js
deleted file mode 100755
index a9a33785..00000000
--- a/packages/server/services/sync/utils/resolveUrl/index.js
+++ /dev/null
@@ -1,20 +0,0 @@
-export default (from, to) => {
- const resolvedUrl = new URL(to, new URL(from, "resolve://"))
-
- if (resolvedUrl.protocol === "resolve:") {
- let { pathname, search, hash } = resolvedUrl
-
- if (to.includes("@")) {
- const fromUrl = new URL(from)
- const toUrl = new URL(to, fromUrl.origin)
-
- pathname = toUrl.pathname
- search = toUrl.search
- hash = toUrl.hash
- }
-
- return pathname + search + hash
- }
-
- return resolvedUrl.toString()
-}
\ No newline at end of file
diff --git a/packages/server/services/users/classes/users/method/getFollowers.js b/packages/server/services/users/classes/users/method/getFollowers.js
index 663284bd..361e5574 100644
--- a/packages/server/services/users/classes/users/method/getFollowers.js
+++ b/packages/server/services/users/classes/users/method/getFollowers.js
@@ -24,7 +24,7 @@ export default async (payload = {}) => {
return followersData
} else {
- const count = await UserFollow.count({
+ const count = await UserFollow.countDocuments({
to: user_id
})
diff --git a/packages/server/services/users/classes/users/method/toggleFollow.js b/packages/server/services/users/classes/users/method/toggleFollow.js
index dbd36af9..5d916d4a 100644
--- a/packages/server/services/users/classes/users/method/toggleFollow.js
+++ b/packages/server/services/users/classes/users/method/toggleFollow.js
@@ -46,6 +46,6 @@ export default async (payload = {}) => {
return {
following: to,
- count: await UserFollow.count({ to: user_id }),
+ count: await UserFollow.countDocuments({ to: user_id }),
}
}
\ No newline at end of file
diff --git a/packages/server/services/users/package.json b/packages/server/services/users/package.json
index 41a56905..52e359d7 100644
--- a/packages/server/services/users/package.json
+++ b/packages/server/services/users/package.json
@@ -1,6 +1,4 @@
{
"name": "users",
- "version": "1.0.0",
- "main": "index.js",
- "license": "MIT"
+ "version": "1.0.0"
}
diff --git a/packages/server/services/users/users.service.js b/packages/server/services/users/users.service.js
index f2a433e2..851448de 100644
--- a/packages/server/services/users/users.service.js
+++ b/packages/server/services/users/users.service.js
@@ -1,4 +1,4 @@
-import { Server } from "linebridge/src/server"
+import { Server } from "linebridge/dist/server"
import DbManager from "@shared-classes/DbManager"
import RedisClient from "@shared-classes/RedisClient"