mirror of
https://github.com/ragestudio/comty.git
synced 2025-06-11 03:24:16 +00:00
move api logics to comty.js
This commit is contained in:
parent
cf394024cd
commit
d306297ac1
@ -13,10 +13,11 @@ const aliases = {
|
|||||||
pages: path.join(__dirname, "src/pages"),
|
pages: path.join(__dirname, "src/pages"),
|
||||||
theme: path.join(__dirname, "src/theme"),
|
theme: path.join(__dirname, "src/theme"),
|
||||||
components: path.join(__dirname, "src/components"),
|
components: path.join(__dirname, "src/components"),
|
||||||
models: path.join(__dirname, "src/models"),
|
|
||||||
utils: path.join(__dirname, "src/utils"),
|
utils: path.join(__dirname, "src/utils"),
|
||||||
layouts: path.join(__dirname, "src/layouts"),
|
layouts: path.join(__dirname, "src/layouts"),
|
||||||
hooks: path.join(__dirname, "src/hooks"),
|
hooks: path.join(__dirname, "src/hooks"),
|
||||||
|
"comty.js": path.join(__dirname, "../", "comty.js", "src"),
|
||||||
|
models: path.join(__dirname, "../comty.js/src/models"),
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = (config = {}) => {
|
module.exports = (config = {}) => {
|
||||||
@ -36,7 +37,7 @@ module.exports = (config = {}) => {
|
|||||||
config.server.port = process.env.listenPort ?? 8000
|
config.server.port = process.env.listenPort ?? 8000
|
||||||
config.server.host = "0.0.0.0"
|
config.server.host = "0.0.0.0"
|
||||||
config.server.fs = {
|
config.server.fs = {
|
||||||
allow: [".."]
|
allow: ["..", "../../"],
|
||||||
}
|
}
|
||||||
|
|
||||||
config.envDir = path.join(__dirname, "environments")
|
config.envDir = path.join(__dirname, "environments")
|
||||||
|
@ -2,30 +2,6 @@ import packagejson from "../package.json"
|
|||||||
import defaultTheme from "../constants/defaultTheme.json"
|
import defaultTheme from "../constants/defaultTheme.json"
|
||||||
import defaultSoundPack from "../constants/defaultSoundPack.json"
|
import defaultSoundPack from "../constants/defaultSoundPack.json"
|
||||||
|
|
||||||
const envOrigins = {
|
|
||||||
"localhost": {
|
|
||||||
mainApi: `http://${window.location.hostname}:3010`,
|
|
||||||
messagingApi: `http://${window.location.hostname}:3020`,
|
|
||||||
livestreamingApi: `http://${window.location.hostname}:3030`,
|
|
||||||
},
|
|
||||||
"development": {
|
|
||||||
mainApi: `https://indev_api.comty.app`,
|
|
||||||
messagingApi: `https://indev_messaging_api.comty.app`,
|
|
||||||
livestreamingApi: `https://indev_livestreaming_api.comty.app`,
|
|
||||||
},
|
|
||||||
"production": {
|
|
||||||
mainApi: "https://api.comty.app",
|
|
||||||
messagingApi: `https://messaging_api.comty.app`,
|
|
||||||
livestreamingApi: `https://livestreaming_api.comty.app`,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function composeRemote(path) {
|
|
||||||
return window.location.hostname.includes("localhost") ? envOrigins["localhost"][path] : envOrigins[process.env.NODE_ENV][path]
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log(`Config loaded with mode: [${process.env.NODE_ENV}]`)
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
package: packagejson,
|
package: packagejson,
|
||||||
defaultTheme: defaultTheme,
|
defaultTheme: defaultTheme,
|
||||||
@ -61,11 +37,6 @@ export default {
|
|||||||
ragestudio_alt: "https://storage.ragestudio.net/rstudio/branding/ragestudio/iso/ragestudio.svg",
|
ragestudio_alt: "https://storage.ragestudio.net/rstudio/branding/ragestudio/iso/ragestudio.svg",
|
||||||
ragestudio_full: "https://storage.ragestudio.net/rstudio/branding/ragestudio/labeled/ragestudio-labeled_white.svg",
|
ragestudio_full: "https://storage.ragestudio.net/rstudio/branding/ragestudio/labeled/ragestudio-labeled_white.svg",
|
||||||
},
|
},
|
||||||
remotes: {
|
|
||||||
mainApi: composeRemote("mainApi"),
|
|
||||||
messagingApi: composeRemote("messagingApi"),
|
|
||||||
livestreamingApi: composeRemote("livestreamingApi"),
|
|
||||||
},
|
|
||||||
app: {
|
app: {
|
||||||
title: packagejson.name,
|
title: packagejson.name,
|
||||||
siteName: "Comty™",
|
siteName: "Comty™",
|
||||||
|
@ -81,9 +81,9 @@ export default {
|
|||||||
const instance = app.cores.api.instance()
|
const instance = app.cores.api.instance()
|
||||||
|
|
||||||
if (instance) {
|
if (instance) {
|
||||||
setServerOrigin(instance.origin)
|
setServerOrigin(instance.mainOrigin)
|
||||||
|
|
||||||
if (instance.origin.startsWith("https")) {
|
if (instance.mainOrigin.startsWith("https")) {
|
||||||
setSecureConnection(true)
|
setSecureConnection(true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import React from "react"
|
import React from "react"
|
||||||
import * as antd from "antd"
|
import * as antd from "antd"
|
||||||
|
|
||||||
import { UserModel } from "models"
|
import UserModel from "models/user"
|
||||||
import { Icons } from "components/Icons"
|
import { Icons } from "components/Icons"
|
||||||
|
|
||||||
import "./index.less"
|
import "./index.less"
|
||||||
|
@ -48,6 +48,7 @@
|
|||||||
"axios": "1.1.3",
|
"axios": "1.1.3",
|
||||||
"buffer": "^6.0.3",
|
"buffer": "^6.0.3",
|
||||||
"classnames": "2.3.1",
|
"classnames": "2.3.1",
|
||||||
|
"dexie": "^3.2.3",
|
||||||
"dompurify": "^3.0.0",
|
"dompurify": "^3.0.0",
|
||||||
"electron-is": "^3.0.0",
|
"electron-is": "^3.0.0",
|
||||||
"electron-log": "^4.4.8",
|
"electron-log": "^4.4.8",
|
||||||
|
406
packages/app/src/cores/api/index.js
Executable file → Normal file
406
packages/app/src/cores/api/index.js
Executable file → Normal file
@ -1,18 +1,14 @@
|
|||||||
import React from "react"
|
|
||||||
import Core from "evite/src/core"
|
import Core from "evite/src/core"
|
||||||
import { Bridge } from "linebridge/dist/client"
|
|
||||||
|
|
||||||
import config from "config"
|
import createClient from "comty.js"
|
||||||
import { SessionModel } from "models"
|
|
||||||
|
|
||||||
export default class ApiCore extends Core {
|
import measurePing from "comty.js/handlers/measurePing"
|
||||||
|
import request from "comty.js/handlers/request"
|
||||||
|
import useRequest from "comty.js/hooks/useRequest"
|
||||||
|
|
||||||
|
export default class APICore extends Core {
|
||||||
static refName = "api"
|
static refName = "api"
|
||||||
static namespace = "api"
|
static namespace = "api"
|
||||||
static depends = ["settings"]
|
|
||||||
|
|
||||||
excludedExpiredExceptionURL = ["/session/regenerate"]
|
|
||||||
|
|
||||||
onExpiredExceptionEvent = false
|
|
||||||
|
|
||||||
instance = null
|
instance = null
|
||||||
|
|
||||||
@ -20,369 +16,53 @@ export default class ApiCore extends Core {
|
|||||||
instance: function () {
|
instance: function () {
|
||||||
return this.instance
|
return this.instance
|
||||||
}.bind(this),
|
}.bind(this),
|
||||||
useRequest: this.useRequest,
|
customRequest: request,
|
||||||
customRequest: this.customRequest.bind(this),
|
|
||||||
request: this.request.bind(this),
|
|
||||||
withEndpoints: this.withEndpoints.bind(this),
|
|
||||||
attach: this.attach.bind(this),
|
|
||||||
createBridge: this.createBridge.bind(this),
|
|
||||||
autenticateWS: this.autenticateWS.bind(this),
|
|
||||||
listenEvent: this.listenEvent.bind(this),
|
listenEvent: this.listenEvent.bind(this),
|
||||||
unlistenEvent: this.unlistenEvent.bind(this),
|
unlistenEvent: this.unlistenEvent.bind(this),
|
||||||
measurePing: this.measurePing.bind(this),
|
measurePing: measurePing,
|
||||||
|
useRequest: useRequest,
|
||||||
}
|
}
|
||||||
|
|
||||||
async attach() {
|
listenEvent(key, handler, instance) {
|
||||||
// get remotes origins from config
|
this.instance.wsInstances[instance ?? "default"].on(key, handler)
|
||||||
const defaultRemotes = config.remotes
|
}
|
||||||
|
|
||||||
// get storaged remotes origins
|
unlistenEvent(key, handler, instance) {
|
||||||
const storedRemotes = await app.cores.settings.get("remotes") ?? {}
|
this.instance.wsInstances[instance ?? "default"].off(key, handler)
|
||||||
|
}
|
||||||
|
|
||||||
const origin = storedRemotes.mainApi ?? defaultRemotes.mainApi
|
async onInitialize() {
|
||||||
|
this.instance = await createClient({
|
||||||
this.instance = this.createBridge({
|
useWs: true,
|
||||||
origin,
|
|
||||||
})
|
})
|
||||||
|
|
||||||
await this.instance.initialize()
|
this.instance.eventBus.on("auth:login_success", () => {
|
||||||
|
app.eventBus.emit("auth:login_success")
|
||||||
|
})
|
||||||
|
|
||||||
console.debug(`[API] Attached to ${origin}`, this.instance)
|
this.instance.eventBus.on("auth:logout_success", () => {
|
||||||
|
app.eventBus.emit("auth:logout_success")
|
||||||
|
})
|
||||||
|
|
||||||
|
this.instance.eventBus.on("session.invalid", (error) => {
|
||||||
|
app.eventBus.emit("session.invalid", error)
|
||||||
|
})
|
||||||
|
|
||||||
|
// make a basic request to check if the API is available
|
||||||
|
await this.instance.instances["default"]({
|
||||||
|
method: "GET",
|
||||||
|
url: "/ping",
|
||||||
|
}).catch((error) => {
|
||||||
|
console.error("[API] Ping error", error)
|
||||||
|
|
||||||
|
throw new Error(`
|
||||||
|
Could not connect to the API.
|
||||||
|
Please check your connection and try again.
|
||||||
|
`)
|
||||||
|
})
|
||||||
|
|
||||||
|
console.debug("[API] Attached to", this.instance)
|
||||||
|
|
||||||
return this.instance
|
return this.instance
|
||||||
}
|
}
|
||||||
|
|
||||||
useRequest(method, ...args) {
|
|
||||||
if (typeof method !== "function") {
|
|
||||||
throw new Error("useRequest: method must be a function")
|
|
||||||
}
|
|
||||||
|
|
||||||
const [loading, setLoading] = React.useState(true)
|
|
||||||
const [result, setResult] = React.useState(null)
|
|
||||||
const [error, setError] = React.useState(null)
|
|
||||||
|
|
||||||
const makeRequest = () => {
|
|
||||||
method(...args)
|
|
||||||
.then((data) => {
|
|
||||||
setResult(data)
|
|
||||||
setLoading(false)
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
setError(err)
|
|
||||||
setLoading(false)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
React.useEffect(() => {
|
|
||||||
makeRequest()
|
|
||||||
}, [])
|
|
||||||
|
|
||||||
return [loading, result, error, makeRequest]
|
|
||||||
}
|
|
||||||
|
|
||||||
async customRequest(
|
|
||||||
request = {
|
|
||||||
method: "GET",
|
|
||||||
},
|
|
||||||
...args
|
|
||||||
) {
|
|
||||||
const instance = request.instance ?? this.instance.httpInterface
|
|
||||||
|
|
||||||
if (!instance) {
|
|
||||||
throw new Error("No instance provided")
|
|
||||||
}
|
|
||||||
|
|
||||||
// handle before request
|
|
||||||
await this.handleBeforeRequest(request)
|
|
||||||
|
|
||||||
if (typeof request === "string") {
|
|
||||||
request = {
|
|
||||||
url: request,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeof request.headers !== "object") {
|
|
||||||
request.headers = {}
|
|
||||||
}
|
|
||||||
|
|
||||||
let result = null
|
|
||||||
|
|
||||||
const makeRequest = async () => {
|
|
||||||
const sessionToken = await SessionModel.token
|
|
||||||
|
|
||||||
if (sessionToken) {
|
|
||||||
request.headers["Authorization"] = `Bearer ${sessionToken}`
|
|
||||||
} else {
|
|
||||||
console.warn("Making a request with no session token")
|
|
||||||
}
|
|
||||||
|
|
||||||
const _result = await instance(request, ...args)
|
|
||||||
.catch((error) => {
|
|
||||||
return error
|
|
||||||
})
|
|
||||||
|
|
||||||
result = _result
|
|
||||||
}
|
|
||||||
|
|
||||||
await makeRequest()
|
|
||||||
|
|
||||||
// handle after request
|
|
||||||
await this.handleAfterRequest(result, makeRequest)
|
|
||||||
|
|
||||||
// if error, throw it
|
|
||||||
if (result instanceof Error) {
|
|
||||||
throw result
|
|
||||||
}
|
|
||||||
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
request(method, endpoint, ...args) {
|
|
||||||
return this.instance.endpoints[method][endpoint](...args)
|
|
||||||
}
|
|
||||||
|
|
||||||
withEndpoints() {
|
|
||||||
return this.instance.endpoints
|
|
||||||
}
|
|
||||||
|
|
||||||
handleBeforeRequest = async (request) => {
|
|
||||||
if (this.onExpiredExceptionEvent) {
|
|
||||||
if (this.excludedExpiredExceptionURL.includes(request.url)) return
|
|
||||||
|
|
||||||
await new Promise((resolve) => {
|
|
||||||
app.eventBus.once("session.regenerated", () => {
|
|
||||||
console.log(`Session has been regenerated, retrying request`)
|
|
||||||
resolve()
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
handleAfterRequest = async (data, callback) => {
|
|
||||||
// handle 401, 403 responses
|
|
||||||
if (data instanceof Error) {
|
|
||||||
if (data.code && (data.code === "ECONNABORTED" || data.code === "ERR_NETWORK")) {
|
|
||||||
console.error(`Request aborted or network error, ignoring`)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
if (data.response.status === 401) {
|
|
||||||
// check if the server issue a refresh token on data
|
|
||||||
if (data.response.data.refreshToken) {
|
|
||||||
console.log(`Session expired, but the server issued a refresh token, handling regeneration event`)
|
|
||||||
|
|
||||||
// handle regeneration event
|
|
||||||
await this.handleRegenerationEvent(data.response.data.refreshToken)
|
|
||||||
|
|
||||||
return await callback()
|
|
||||||
}
|
|
||||||
|
|
||||||
// check if route is from "session" namespace
|
|
||||||
if (data.config.url.includes("/session")) {
|
|
||||||
return window.app.eventBus.emit("session.invalid", "Session expired, but the server did not issue a refresh token")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (data.response.status === 403) {
|
|
||||||
if (data.config.url.includes("/session")) {
|
|
||||||
return window.app.eventBus.emit("session.invalid", "Session not valid or not existent")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
handleRegenerationEvent = async (refreshToken) => {
|
|
||||||
window.app.eventBus.emit("session.expiredExceptionEvent", refreshToken)
|
|
||||||
|
|
||||||
this.onExpiredExceptionEvent = true
|
|
||||||
|
|
||||||
const expiredToken = await SessionModel.token
|
|
||||||
|
|
||||||
// send request to regenerate token
|
|
||||||
const response = await this.customRequest({
|
|
||||||
method: "POST",
|
|
||||||
url: "/session/regenerate",
|
|
||||||
data: {
|
|
||||||
expiredToken: expiredToken,
|
|
||||||
refreshToken,
|
|
||||||
}
|
|
||||||
}).catch((error) => {
|
|
||||||
console.error(`Failed to regenerate token: ${error.message}`)
|
|
||||||
return false
|
|
||||||
})
|
|
||||||
|
|
||||||
if (!response) {
|
|
||||||
return window.app.eventBus.emit("session.invalid", "Failed to regenerate token")
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!response.data?.token) {
|
|
||||||
return window.app.eventBus.emit("session.invalid", "Failed to regenerate token, invalid server response.")
|
|
||||||
}
|
|
||||||
|
|
||||||
// set new token
|
|
||||||
SessionModel.token = response.data.token
|
|
||||||
|
|
||||||
//this.namespaces["main"].internalAbortController.abort()
|
|
||||||
|
|
||||||
this.onExpiredExceptionEvent = false
|
|
||||||
|
|
||||||
// emit event
|
|
||||||
window.app.eventBus.emit("session.regenerated")
|
|
||||||
}
|
|
||||||
|
|
||||||
createBridge(params = {}) {
|
|
||||||
const getSessionContext = async () => {
|
|
||||||
const obj = {}
|
|
||||||
const token = await SessionModel.token
|
|
||||||
|
|
||||||
if (token) {
|
|
||||||
// append token to context
|
|
||||||
obj.headers = {
|
|
||||||
Authorization: `Bearer ${token ?? null}`,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return obj
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeof params !== "object") {
|
|
||||||
throw new Error("Params must be an object")
|
|
||||||
}
|
|
||||||
|
|
||||||
const bridgeOptions = {
|
|
||||||
wsOptions: {
|
|
||||||
autoConnect: false,
|
|
||||||
},
|
|
||||||
onBeforeRequest: this.handleBeforeRequest,
|
|
||||||
onRequest: getSessionContext,
|
|
||||||
onResponse: this.handleAfterRequest,
|
|
||||||
...params,
|
|
||||||
origin: params.httpAddress ?? config.remotes.mainApi,
|
|
||||||
}
|
|
||||||
|
|
||||||
const bridge = new Bridge(bridgeOptions)
|
|
||||||
|
|
||||||
// handle main ws onEvents
|
|
||||||
const mainSocket = bridge.wsInterface.sockets["main"]
|
|
||||||
|
|
||||||
mainSocket.on("authenticated", () => {
|
|
||||||
console.debug("[WS] Authenticated")
|
|
||||||
})
|
|
||||||
|
|
||||||
mainSocket.on("authenticateFailed", (error) => {
|
|
||||||
console.error("[WS] Authenticate Failed", error)
|
|
||||||
})
|
|
||||||
|
|
||||||
mainSocket.on("connect", () => {
|
|
||||||
if (this.ctx.eventBus) {
|
|
||||||
this.ctx.eventBus.emit(`api.ws.main.connect`)
|
|
||||||
}
|
|
||||||
|
|
||||||
console.debug("[WS] Connected, authenticating...")
|
|
||||||
|
|
||||||
this.autenticateWS(mainSocket)
|
|
||||||
})
|
|
||||||
|
|
||||||
mainSocket.on("disconnect", (...context) => {
|
|
||||||
if (this.ctx.eventBus) {
|
|
||||||
this.ctx.eventBus.emit(`api.ws.main.disconnect`, ...context)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
mainSocket.on("connect_error", (...context) => {
|
|
||||||
if (this.ctx.eventBus) {
|
|
||||||
this.ctx.eventBus.emit(`api.ws.main.connect_error`, ...context)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
mainSocket.onAny((event, ...args) => {
|
|
||||||
console.debug(`[WS] Recived Event (${event})`, ...args)
|
|
||||||
})
|
|
||||||
|
|
||||||
// mainSocket.onAnyOutgoing((event, ...args) => {
|
|
||||||
// console.debug(`[WS] Sent Event (${event})`, ...args)
|
|
||||||
// })
|
|
||||||
|
|
||||||
return bridge
|
|
||||||
}
|
|
||||||
|
|
||||||
listenEvent(event, callback) {
|
|
||||||
if (!this.instance.wsInterface) {
|
|
||||||
throw new Error("API is not attached")
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.instance.wsInterface.sockets["main"].on(event, callback)
|
|
||||||
}
|
|
||||||
|
|
||||||
unlistenEvent(event, callback) {
|
|
||||||
if (!this.instance.wsInterface) {
|
|
||||||
throw new Error("API is not attached")
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.instance.wsInterface.sockets["main"].off(event, callback)
|
|
||||||
}
|
|
||||||
|
|
||||||
async autenticateWS(socket) {
|
|
||||||
const token = await SessionModel.token
|
|
||||||
|
|
||||||
if (!token) {
|
|
||||||
return console.error("Failed to authenticate WS, no token found")
|
|
||||||
}
|
|
||||||
|
|
||||||
socket.emit("authenticate", {
|
|
||||||
token,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
async measurePing() {
|
|
||||||
const timings = {}
|
|
||||||
|
|
||||||
const promises = [
|
|
||||||
new Promise(async (resolve) => {
|
|
||||||
const start = Date.now()
|
|
||||||
|
|
||||||
this.customRequest({
|
|
||||||
method: "GET",
|
|
||||||
url: "/ping",
|
|
||||||
})
|
|
||||||
.then(() => {
|
|
||||||
// set http timing in ms
|
|
||||||
timings.http = Date.now() - start
|
|
||||||
|
|
||||||
resolve()
|
|
||||||
})
|
|
||||||
.catch(() => {
|
|
||||||
timings.http = "failed"
|
|
||||||
resolve()
|
|
||||||
})
|
|
||||||
|
|
||||||
setTimeout(() => {
|
|
||||||
timings.http = "failed"
|
|
||||||
|
|
||||||
resolve()
|
|
||||||
}, 10000)
|
|
||||||
}),
|
|
||||||
new Promise((resolve) => {
|
|
||||||
const start = Date.now()
|
|
||||||
|
|
||||||
this.instance.wsInterface.sockets["main"].on("pong", () => {
|
|
||||||
timings.ws = Date.now() - start
|
|
||||||
|
|
||||||
resolve()
|
|
||||||
})
|
|
||||||
|
|
||||||
this.instance.wsInterface.sockets["main"].emit("ping")
|
|
||||||
|
|
||||||
setTimeout(() => {
|
|
||||||
timings.ws = "failed"
|
|
||||||
|
|
||||||
resolve()
|
|
||||||
}, 10000)
|
|
||||||
})
|
|
||||||
]
|
|
||||||
|
|
||||||
await Promise.all(promises)
|
|
||||||
|
|
||||||
return timings
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -1,52 +0,0 @@
|
|||||||
import SessionModel from "../session"
|
|
||||||
|
|
||||||
export default class AuthModel {
|
|
||||||
static login = async (payload) => {
|
|
||||||
const response = await app.cores.api.customRequest({
|
|
||||||
method: "post",
|
|
||||||
url: "/auth/login",
|
|
||||||
data: {
|
|
||||||
username: payload.username, //window.btoa(payload.username),
|
|
||||||
password: payload.password, //window.btoa(payload.password),
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
SessionModel.token = response.data.token
|
|
||||||
|
|
||||||
app.eventBus.emit("auth:login_success")
|
|
||||||
|
|
||||||
return response.data
|
|
||||||
}
|
|
||||||
|
|
||||||
static logout = async () => {
|
|
||||||
await SessionModel.destroyCurrentSession()
|
|
||||||
|
|
||||||
SessionModel.removeToken()
|
|
||||||
|
|
||||||
app.eventBus.emit("auth:logout_success")
|
|
||||||
}
|
|
||||||
|
|
||||||
static async register(payload) {
|
|
||||||
const { username, password, email } = payload
|
|
||||||
|
|
||||||
const response = await app.cores.api.customRequest({
|
|
||||||
method: "post",
|
|
||||||
url: "/auth/register",
|
|
||||||
data: {
|
|
||||||
username,
|
|
||||||
password,
|
|
||||||
email,
|
|
||||||
}
|
|
||||||
}).catch((error) => {
|
|
||||||
console.error(error)
|
|
||||||
|
|
||||||
return false
|
|
||||||
})
|
|
||||||
|
|
||||||
if (!response) {
|
|
||||||
throw new Error("Unable to register user")
|
|
||||||
}
|
|
||||||
|
|
||||||
return response
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,79 +0,0 @@
|
|||||||
export default class FeedModel {
|
|
||||||
static async getMusicFeed({ trim, limit } = {}) {
|
|
||||||
const { data } = await app.cores.api.customRequest({
|
|
||||||
method: "GET",
|
|
||||||
url: `/feed/music`,
|
|
||||||
params: {
|
|
||||||
trim: trim ?? 0,
|
|
||||||
limit: limit ?? window.app.cores.settings.get("feed_max_fetch"),
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
return data
|
|
||||||
}
|
|
||||||
|
|
||||||
static async getGlobalMusicFeed({ trim, limit } = {}) {
|
|
||||||
const { data } = await app.cores.api.customRequest({
|
|
||||||
method: "GET",
|
|
||||||
url: `/feed/music/global`,
|
|
||||||
params: {
|
|
||||||
trim: trim ?? 0,
|
|
||||||
limit: limit ?? window.app.cores.settings.get("feed_max_fetch"),
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
return data
|
|
||||||
}
|
|
||||||
|
|
||||||
static async getTimelineFeed({ trim, limit } = {}) {
|
|
||||||
const { data } = await app.cores.api.customRequest({
|
|
||||||
method: "GET",
|
|
||||||
url: `/feed/timeline`,
|
|
||||||
params: {
|
|
||||||
trim: trim ?? 0,
|
|
||||||
limit: limit ?? window.app.cores.settings.get("feed_max_fetch"),
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
return data
|
|
||||||
}
|
|
||||||
|
|
||||||
static async getPostsFeed({ trim, limit } = {}) {
|
|
||||||
const { data } = await app.cores.api.customRequest({
|
|
||||||
method: "GET",
|
|
||||||
url: `/feed/posts`,
|
|
||||||
params: {
|
|
||||||
trim: trim ?? 0,
|
|
||||||
limit: limit ?? window.app.cores.settings.get("feed_max_fetch"),
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
return data
|
|
||||||
}
|
|
||||||
|
|
||||||
static async getPlaylistsFeed({ trim, limit } = {}) {
|
|
||||||
const { data } = await app.cores.api.customRequest({
|
|
||||||
method: "GET",
|
|
||||||
url: `/feed/playlists`,
|
|
||||||
params: {
|
|
||||||
trim: trim ?? 0,
|
|
||||||
limit: limit ?? window.app.cores.settings.get("feed_max_fetch"),
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
return data
|
|
||||||
}
|
|
||||||
|
|
||||||
static async search(keywords, params = {}) {
|
|
||||||
const { data } = await app.cores.api.customRequest({
|
|
||||||
method: "GET",
|
|
||||||
url: `/search`,
|
|
||||||
params: {
|
|
||||||
keywords: keywords,
|
|
||||||
params: params
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
return data
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,57 +0,0 @@
|
|||||||
export default class FilesModel {
|
|
||||||
static async uploadFile(file, ...args) {
|
|
||||||
const result = await app.cores.remoteStorage.uploadFile(file, ...args)
|
|
||||||
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
static async deprecated_uploadFile(file) {
|
|
||||||
console.log("uploadFile", file)
|
|
||||||
|
|
||||||
// get the file from the payload
|
|
||||||
if (!file) {
|
|
||||||
throw new Error("File is required")
|
|
||||||
}
|
|
||||||
|
|
||||||
// create a new form data
|
|
||||||
const formData = new FormData()
|
|
||||||
|
|
||||||
// append the file to the form data
|
|
||||||
formData.append("files", file)
|
|
||||||
|
|
||||||
// send the request
|
|
||||||
const uploadRequest = await app.cores.api.customRequest({
|
|
||||||
method: "POST",
|
|
||||||
url: "/files/upload",
|
|
||||||
data: formData,
|
|
||||||
}).catch((err) => {
|
|
||||||
throw new Error(err.response.data.message)
|
|
||||||
})
|
|
||||||
|
|
||||||
if (uploadRequest.data.files.length === 0) {
|
|
||||||
throw new Error("Upload failed, empty response")
|
|
||||||
}
|
|
||||||
|
|
||||||
return uploadRequest.data.files[0]
|
|
||||||
}
|
|
||||||
|
|
||||||
static async uploadFiles(files) {
|
|
||||||
// get the file from the payload
|
|
||||||
if (!files) {
|
|
||||||
throw new Error("Files are required")
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!Array.isArray(files)) {
|
|
||||||
throw new Error("Files must be an array")
|
|
||||||
}
|
|
||||||
|
|
||||||
const resultFiles = []
|
|
||||||
|
|
||||||
for await (const file of files) {
|
|
||||||
const result = await FilesModel.uploadFile(file)
|
|
||||||
resultFiles.push(result)
|
|
||||||
}
|
|
||||||
|
|
||||||
return resultFiles
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,47 +0,0 @@
|
|||||||
import { SessionModel } from "models"
|
|
||||||
|
|
||||||
export default class FollowsModel {
|
|
||||||
static async imFollowing(user_id) {
|
|
||||||
if (!user_id) {
|
|
||||||
throw new Error("user_id is required")
|
|
||||||
}
|
|
||||||
|
|
||||||
const response = await app.cores.api.customRequest( {
|
|
||||||
method: "GET",
|
|
||||||
url: `/follow/user/${user_id}`,
|
|
||||||
})
|
|
||||||
|
|
||||||
return response.data
|
|
||||||
}
|
|
||||||
|
|
||||||
static async getFollowers(user_id) {
|
|
||||||
if (!user_id) {
|
|
||||||
// set current user_id
|
|
||||||
user_id = SessionModel.user_id
|
|
||||||
}
|
|
||||||
|
|
||||||
const response = await app.cores.api.customRequest( {
|
|
||||||
method: "GET",
|
|
||||||
url: `/follow/user/${user_id}/followers`,
|
|
||||||
})
|
|
||||||
|
|
||||||
return response.data
|
|
||||||
}
|
|
||||||
|
|
||||||
static async toogleFollow({ user_id, username }) {
|
|
||||||
if (!user_id && !username) {
|
|
||||||
throw new Error("user_id or username is required")
|
|
||||||
}
|
|
||||||
|
|
||||||
const response = await app.cores.api.customRequest( {
|
|
||||||
method: "POST",
|
|
||||||
url: "/follow/user/toogle",
|
|
||||||
data: {
|
|
||||||
user_id: user_id,
|
|
||||||
username: username
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
return response.data
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,3 +0,0 @@
|
|||||||
export { default as SessionModel } from "./session"
|
|
||||||
export { default as UserModel } from "./user"
|
|
||||||
export { default as FollowsModel } from "./follows"
|
|
@ -1,89 +0,0 @@
|
|||||||
import axios from "axios"
|
|
||||||
import config from "config"
|
|
||||||
|
|
||||||
export default class Livestream {
|
|
||||||
static instance = axios.create({
|
|
||||||
baseURL: config.remotes.livestreamingApi,
|
|
||||||
})
|
|
||||||
|
|
||||||
static async deleteProfile(profile_id) {
|
|
||||||
const request = await app.cores.api.customRequest({
|
|
||||||
method: "DELETE",
|
|
||||||
url: `/tv/streaming/profile`,
|
|
||||||
data: {
|
|
||||||
profile_id
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
return request.data
|
|
||||||
}
|
|
||||||
|
|
||||||
static async postProfile(payload) {
|
|
||||||
const request = await app.cores.api.customRequest({
|
|
||||||
method: "POST",
|
|
||||||
url: `/tv/streaming/profile`,
|
|
||||||
data: payload,
|
|
||||||
})
|
|
||||||
|
|
||||||
return request.data
|
|
||||||
}
|
|
||||||
|
|
||||||
static async getProfiles() {
|
|
||||||
const request = await app.cores.api.customRequest({
|
|
||||||
method: "GET",
|
|
||||||
url: `/tv/streaming/profiles`,
|
|
||||||
})
|
|
||||||
|
|
||||||
return request.data
|
|
||||||
}
|
|
||||||
|
|
||||||
static async regenerateStreamingKey(profile_id) {
|
|
||||||
const request = await app.cores.api.customRequest({
|
|
||||||
method: "POST",
|
|
||||||
url: `/tv/streaming/regenerate_key`,
|
|
||||||
data: {
|
|
||||||
profile_id
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
return request.data
|
|
||||||
}
|
|
||||||
|
|
||||||
static async getCategories(key) {
|
|
||||||
const request = await app.cores.api.customRequest({
|
|
||||||
method: "GET",
|
|
||||||
url: `/tv/streaming/categories`,
|
|
||||||
params: {
|
|
||||||
key,
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
return request.data
|
|
||||||
}
|
|
||||||
|
|
||||||
static async getLivestream(payload = {}) {
|
|
||||||
if (!payload.username) {
|
|
||||||
throw new Error("Username is required")
|
|
||||||
}
|
|
||||||
|
|
||||||
let request = await app.cores.api.customRequest({
|
|
||||||
method: "GET",
|
|
||||||
url: `/tv/streams`,
|
|
||||||
params: {
|
|
||||||
username: payload.username,
|
|
||||||
profile_id: payload.profile_id,
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
return request.data
|
|
||||||
}
|
|
||||||
|
|
||||||
static async getLivestreams() {
|
|
||||||
const request = await app.cores.api.customRequest({
|
|
||||||
method: "GET",
|
|
||||||
url: `/tv/streams`,
|
|
||||||
})
|
|
||||||
|
|
||||||
return request.data
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,14 +0,0 @@
|
|||||||
export class MusicModel {
|
|
||||||
static get bridge() {
|
|
||||||
return window.app?.cores.api.withEndpoints()
|
|
||||||
}
|
|
||||||
|
|
||||||
static async createSpaceRoom() {
|
|
||||||
const { data } = await app.cores.api.customRequest( {
|
|
||||||
method: "post",
|
|
||||||
url: `/music/create_space_room`,
|
|
||||||
})
|
|
||||||
|
|
||||||
return data
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,46 +0,0 @@
|
|||||||
export default class PlaylistsModel {
|
|
||||||
static async putPlaylist(payload) {
|
|
||||||
if (!payload) {
|
|
||||||
throw new Error("Payload is required")
|
|
||||||
}
|
|
||||||
|
|
||||||
const { data } = await app.cores.api.customRequest({
|
|
||||||
method: "PUT",
|
|
||||||
url: `/playlist`,
|
|
||||||
data: payload,
|
|
||||||
})
|
|
||||||
|
|
||||||
return data
|
|
||||||
}
|
|
||||||
|
|
||||||
static async getPlaylist(id) {
|
|
||||||
const { data } = await app.cores.api.customRequest({
|
|
||||||
method: "GET",
|
|
||||||
url: `/playlist/data/${id}`,
|
|
||||||
})
|
|
||||||
|
|
||||||
return data
|
|
||||||
}
|
|
||||||
|
|
||||||
static async getMyReleases() {
|
|
||||||
const { data } = await app.cores.api.customRequest({
|
|
||||||
method: "GET",
|
|
||||||
url: `/playlist/self`,
|
|
||||||
})
|
|
||||||
|
|
||||||
return data
|
|
||||||
}
|
|
||||||
|
|
||||||
static async deletePlaylist(id) {
|
|
||||||
if (!id) {
|
|
||||||
throw new Error("ID is required")
|
|
||||||
}
|
|
||||||
|
|
||||||
const { data } = await app.cores.api.customRequest({
|
|
||||||
method: "DELETE",
|
|
||||||
url: `/playlist/${id}`,
|
|
||||||
})
|
|
||||||
|
|
||||||
return data
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,189 +0,0 @@
|
|||||||
export default class Post {
|
|
||||||
static get bridge() {
|
|
||||||
return window.app?.cores.api.withEndpoints()
|
|
||||||
}
|
|
||||||
|
|
||||||
static get maxPostTextLength() {
|
|
||||||
return 3200
|
|
||||||
}
|
|
||||||
|
|
||||||
static get maxCommentLength() {
|
|
||||||
return 1200
|
|
||||||
}
|
|
||||||
|
|
||||||
static async getPost({ post_id }) {
|
|
||||||
if (!post_id) {
|
|
||||||
throw new Error("Post ID is required")
|
|
||||||
}
|
|
||||||
|
|
||||||
const { data } = await app.cores.api.customRequest( {
|
|
||||||
method: "GET",
|
|
||||||
url: `/posts/post/${post_id}`,
|
|
||||||
})
|
|
||||||
|
|
||||||
return data
|
|
||||||
}
|
|
||||||
|
|
||||||
static async getPostComments({ post_id }) {
|
|
||||||
if (!post_id) {
|
|
||||||
throw new Error("Post ID is required")
|
|
||||||
}
|
|
||||||
|
|
||||||
const { data } = await app.cores.api.customRequest( {
|
|
||||||
method: "GET",
|
|
||||||
url: `/comments/post/${post_id}`,
|
|
||||||
})
|
|
||||||
|
|
||||||
return data
|
|
||||||
}
|
|
||||||
|
|
||||||
static async sendComment({ post_id, comment }) {
|
|
||||||
if (!post_id || !comment) {
|
|
||||||
throw new Error("Post ID and/or comment are required")
|
|
||||||
}
|
|
||||||
|
|
||||||
const request = await app.cores.api.customRequest( {
|
|
||||||
method: "POST",
|
|
||||||
url: `/comments/post/${post_id}`,
|
|
||||||
data: {
|
|
||||||
message: comment,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
return request
|
|
||||||
}
|
|
||||||
|
|
||||||
static async deleteComment({ post_id, comment_id }) {
|
|
||||||
if (!post_id || !comment_id) {
|
|
||||||
throw new Error("Post ID and/or comment ID are required")
|
|
||||||
}
|
|
||||||
|
|
||||||
const request = await app.cores.api.customRequest( {
|
|
||||||
method: "DELETE",
|
|
||||||
url: `/comments/post/${post_id}/${comment_id}`,
|
|
||||||
})
|
|
||||||
|
|
||||||
return request
|
|
||||||
}
|
|
||||||
|
|
||||||
static async getExplorePosts({ trim, limit }) {
|
|
||||||
if (!Post.bridge) {
|
|
||||||
throw new Error("Bridge is not available")
|
|
||||||
}
|
|
||||||
|
|
||||||
const { data } = await app.cores.api.customRequest( {
|
|
||||||
method: "GET",
|
|
||||||
url: `/posts/explore`,
|
|
||||||
params: {
|
|
||||||
trim: trim ?? 0,
|
|
||||||
limit: limit ?? window.app.cores.settings.get("feed_max_fetch"),
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
return data
|
|
||||||
}
|
|
||||||
|
|
||||||
static async getSavedPosts({ trim, limit }) {
|
|
||||||
if (!Post.bridge) {
|
|
||||||
throw new Error("Bridge is not available")
|
|
||||||
}
|
|
||||||
|
|
||||||
const { data } = await app.cores.api.customRequest( {
|
|
||||||
method: "GET",
|
|
||||||
url: `/posts/saved`,
|
|
||||||
params: {
|
|
||||||
trim: trim ?? 0,
|
|
||||||
limit: limit ?? window.app.cores.settings.get("feed_max_fetch"),
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
return data
|
|
||||||
}
|
|
||||||
|
|
||||||
static async getUserPosts({ user_id, trim, limit }) {
|
|
||||||
if (!Post.bridge) {
|
|
||||||
throw new Error("Bridge is not available")
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!user_id) {
|
|
||||||
// use current user_id
|
|
||||||
user_id = app.userData?._id
|
|
||||||
}
|
|
||||||
|
|
||||||
const { data } = await app.cores.api.customRequest( {
|
|
||||||
method: "GET",
|
|
||||||
url: `/posts/user/${user_id}`,
|
|
||||||
params: {
|
|
||||||
trim: trim ?? 0,
|
|
||||||
limit: limit ?? window.app.cores.settings.get("feed_max_fetch"),
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
return data
|
|
||||||
}
|
|
||||||
|
|
||||||
static async toogleLike({ post_id }) {
|
|
||||||
if (!Post.bridge) {
|
|
||||||
throw new Error("Bridge is not available")
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!post_id) {
|
|
||||||
throw new Error("Post ID is required")
|
|
||||||
}
|
|
||||||
|
|
||||||
const { data } = await app.cores.api.customRequest( {
|
|
||||||
method: "POST",
|
|
||||||
url: `/posts/${post_id}/toogle_like`,
|
|
||||||
})
|
|
||||||
|
|
||||||
return data
|
|
||||||
}
|
|
||||||
|
|
||||||
static async toogleSave({ post_id }) {
|
|
||||||
if (!Post.bridge) {
|
|
||||||
throw new Error("Bridge is not available")
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!post_id) {
|
|
||||||
throw new Error("Post ID is required")
|
|
||||||
}
|
|
||||||
|
|
||||||
const { data } = await app.cores.api.customRequest( {
|
|
||||||
method: "POST",
|
|
||||||
url: `/posts/${post_id}/toogle_save`,
|
|
||||||
})
|
|
||||||
|
|
||||||
return data
|
|
||||||
}
|
|
||||||
|
|
||||||
static async create(payload) {
|
|
||||||
if (!Post.bridge) {
|
|
||||||
throw new Error("Bridge is not available")
|
|
||||||
}
|
|
||||||
|
|
||||||
const { data } = await app.cores.api.customRequest( {
|
|
||||||
method: "POST",
|
|
||||||
url: `/posts/new`,
|
|
||||||
data: payload,
|
|
||||||
})
|
|
||||||
|
|
||||||
return data
|
|
||||||
}
|
|
||||||
|
|
||||||
static async deletePost({ post_id }) {
|
|
||||||
if (!Post.bridge) {
|
|
||||||
throw new Error("Bridge is not available")
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!post_id) {
|
|
||||||
throw new Error("Post ID is required")
|
|
||||||
}
|
|
||||||
|
|
||||||
const { data } = await app.cores.api.customRequest( {
|
|
||||||
method: "DELETE",
|
|
||||||
url: `/posts/${post_id}`,
|
|
||||||
})
|
|
||||||
|
|
||||||
return data
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,114 +0,0 @@
|
|||||||
import cookies from "js-cookie"
|
|
||||||
import jwt_decode from "jwt-decode"
|
|
||||||
import config from "config"
|
|
||||||
|
|
||||||
export default class Session {
|
|
||||||
static storageTokenKey = config.app?.storage?.token ?? "token"
|
|
||||||
|
|
||||||
static get token() {
|
|
||||||
return cookies.get(this.storageTokenKey)
|
|
||||||
}
|
|
||||||
|
|
||||||
static set token(token) {
|
|
||||||
return cookies.set(this.storageTokenKey, token)
|
|
||||||
}
|
|
||||||
|
|
||||||
static get user_id() {
|
|
||||||
return this.getDecodedToken()?.user_id
|
|
||||||
}
|
|
||||||
|
|
||||||
static get session_uuid() {
|
|
||||||
return this.getDecodedToken()?.session_uuid
|
|
||||||
}
|
|
||||||
|
|
||||||
static getDecodedToken() {
|
|
||||||
const token = this.token
|
|
||||||
|
|
||||||
return token && jwt_decode(token)
|
|
||||||
}
|
|
||||||
|
|
||||||
static async getAllSessions() {
|
|
||||||
const response = await app.cores.api.customRequest({
|
|
||||||
method: "get",
|
|
||||||
url: "/session/all"
|
|
||||||
})
|
|
||||||
|
|
||||||
return response.data
|
|
||||||
}
|
|
||||||
|
|
||||||
static async getCurrentSession() {
|
|
||||||
const response = await app.cores.api.customRequest({
|
|
||||||
method: "get",
|
|
||||||
url: "/session/current"
|
|
||||||
})
|
|
||||||
|
|
||||||
return response.data
|
|
||||||
}
|
|
||||||
|
|
||||||
static async getTokenValidation() {
|
|
||||||
const session = await Session.token
|
|
||||||
|
|
||||||
const response = await app.cores.api.customRequest({
|
|
||||||
method: "get",
|
|
||||||
url: "/session/validate",
|
|
||||||
data: {
|
|
||||||
session: session
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
return response.data
|
|
||||||
}
|
|
||||||
|
|
||||||
static removeToken() {
|
|
||||||
return cookies.remove(Session.storageTokenKey)
|
|
||||||
}
|
|
||||||
|
|
||||||
static async destroyCurrentSession() {
|
|
||||||
const token = await Session.token
|
|
||||||
const session = await Session.getDecodedToken()
|
|
||||||
|
|
||||||
if (!session || !token) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
const response = await app.cores.api.customRequest({
|
|
||||||
method: "delete",
|
|
||||||
url: "/session/current"
|
|
||||||
}).catch((error) => {
|
|
||||||
console.error(error)
|
|
||||||
|
|
||||||
return false
|
|
||||||
})
|
|
||||||
|
|
||||||
Session.removeToken()
|
|
||||||
|
|
||||||
window.app.eventBus.emit("session.destroyed")
|
|
||||||
|
|
||||||
return response.data
|
|
||||||
}
|
|
||||||
|
|
||||||
static async destroyAllSessions() {
|
|
||||||
const session = await Session.getDecodedToken()
|
|
||||||
|
|
||||||
if (!session) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
const response = await app.cores.api.customRequest({
|
|
||||||
method: "delete",
|
|
||||||
url: "/session/all"
|
|
||||||
})
|
|
||||||
|
|
||||||
Session.removeToken()
|
|
||||||
|
|
||||||
window.app.eventBus.emit("session.destroyed")
|
|
||||||
|
|
||||||
return response.data
|
|
||||||
}
|
|
||||||
|
|
||||||
static async isCurrentTokenValid() {
|
|
||||||
const health = await Session.getTokenValidation()
|
|
||||||
|
|
||||||
return health.valid
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,87 +0,0 @@
|
|||||||
export default class SpotifySyncModel {
|
|
||||||
static get spotify_redirect_uri() {
|
|
||||||
return window.location.origin + "/callbacks/sync/spotify"
|
|
||||||
}
|
|
||||||
|
|
||||||
static get spotify_authorize_endpoint() {
|
|
||||||
return "https://accounts.spotify.com/authorize?response_type=code&client_id={{client_id}}&scope={{scope}}&redirect_uri={{redirect_uri}}&response_type=code"
|
|
||||||
}
|
|
||||||
|
|
||||||
static async authorizeAccount() {
|
|
||||||
const scopes = [
|
|
||||||
"user-read-private",
|
|
||||||
"user-modify-playback-state",
|
|
||||||
"user-read-currently-playing",
|
|
||||||
"user-read-playback-state",
|
|
||||||
"streaming",
|
|
||||||
]
|
|
||||||
|
|
||||||
const { client_id } = await SpotifySyncModel.get_client_id()
|
|
||||||
|
|
||||||
const parsedUrl = SpotifySyncModel.spotify_authorize_endpoint
|
|
||||||
.replace("{{client_id}}", client_id)
|
|
||||||
.replace("{{scope}}", scopes.join(" "))
|
|
||||||
.replace("{{redirect_uri}}", SpotifySyncModel.spotify_redirect_uri)
|
|
||||||
|
|
||||||
// open on a new tab
|
|
||||||
window.open(parsedUrl, "_blank")
|
|
||||||
}
|
|
||||||
|
|
||||||
static async get_client_id() {
|
|
||||||
const { data } = await app.cores.api.customRequest( {
|
|
||||||
method: "GET",
|
|
||||||
url: `/sync/spotify/client_id`,
|
|
||||||
})
|
|
||||||
|
|
||||||
return data
|
|
||||||
}
|
|
||||||
|
|
||||||
static async syncAuthCode(code) {
|
|
||||||
const { data } = await app.cores.api.customRequest( {
|
|
||||||
method: "POST",
|
|
||||||
url: `/sync/spotify/auth`,
|
|
||||||
data: {
|
|
||||||
redirect_uri: SpotifySyncModel.spotify_redirect_uri,
|
|
||||||
code,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
return data
|
|
||||||
}
|
|
||||||
|
|
||||||
static async unlinkAccount() {
|
|
||||||
const { data } = await app.cores.api.customRequest( {
|
|
||||||
method: "POST",
|
|
||||||
url: `/sync/spotify/unlink`,
|
|
||||||
})
|
|
||||||
|
|
||||||
return data
|
|
||||||
}
|
|
||||||
|
|
||||||
static async isAuthorized() {
|
|
||||||
const { data } = await app.cores.api.customRequest( {
|
|
||||||
method: "GET",
|
|
||||||
url: `/sync/spotify/is_authorized`,
|
|
||||||
})
|
|
||||||
|
|
||||||
return data
|
|
||||||
}
|
|
||||||
|
|
||||||
static async getData() {
|
|
||||||
const { data } = await app.cores.api.customRequest( {
|
|
||||||
method: "GET",
|
|
||||||
url: `/sync/spotify/data`,
|
|
||||||
})
|
|
||||||
|
|
||||||
return data
|
|
||||||
}
|
|
||||||
|
|
||||||
static async getCurrentPlaying() {
|
|
||||||
const { data } = await app.cores.api.customRequest( {
|
|
||||||
method: "GET",
|
|
||||||
url: `/sync/spotify/currently_playing`,
|
|
||||||
})
|
|
||||||
|
|
||||||
return data
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,11 +0,0 @@
|
|||||||
import SpotifySyncModel from "./cores/spotifyCore"
|
|
||||||
|
|
||||||
export default class SyncModel {
|
|
||||||
static get bridge() {
|
|
||||||
return window.app?.cores.api.withEndpoints()
|
|
||||||
}
|
|
||||||
|
|
||||||
static get spotifyCore() {
|
|
||||||
return SpotifySyncModel
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,158 +0,0 @@
|
|||||||
import SessionModel from "../session"
|
|
||||||
|
|
||||||
export default class User {
|
|
||||||
static async data(payload = {}) {
|
|
||||||
let {
|
|
||||||
username,
|
|
||||||
user_id,
|
|
||||||
} = payload
|
|
||||||
|
|
||||||
if (!username && !user_id) {
|
|
||||||
user_id = SessionModel.user_id
|
|
||||||
}
|
|
||||||
|
|
||||||
if (username && !user_id) {
|
|
||||||
// resolve user_id from username
|
|
||||||
const resolveResponse = await app.cores.api.customRequest({
|
|
||||||
method: "GET",
|
|
||||||
url: `/user/user_id/${username}`,
|
|
||||||
})
|
|
||||||
|
|
||||||
user_id = resolveResponse.data.user_id
|
|
||||||
}
|
|
||||||
|
|
||||||
const response = await app.cores.api.customRequest({
|
|
||||||
method: "GET",
|
|
||||||
url: `/user/${user_id}/data`,
|
|
||||||
})
|
|
||||||
|
|
||||||
return response.data
|
|
||||||
}
|
|
||||||
|
|
||||||
static async updateData(payload) {
|
|
||||||
const response = await app.cores.api.customRequest({
|
|
||||||
method: "POST",
|
|
||||||
url: "/user/self/update_data",
|
|
||||||
data: {
|
|
||||||
update: payload,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
return response.data
|
|
||||||
}
|
|
||||||
|
|
||||||
static async unsetFullName() {
|
|
||||||
const response = await app.cores.api.customRequest({
|
|
||||||
method: "DELETE",
|
|
||||||
url: "/user/self/public_name",
|
|
||||||
})
|
|
||||||
|
|
||||||
return response.data
|
|
||||||
}
|
|
||||||
|
|
||||||
static async selfRoles() {
|
|
||||||
const response = await app.cores.api.customRequest({
|
|
||||||
method: "GET",
|
|
||||||
url: "/roles/self",
|
|
||||||
})
|
|
||||||
|
|
||||||
return response.data
|
|
||||||
}
|
|
||||||
|
|
||||||
static async haveRole(role) {
|
|
||||||
const roles = await User.selfRoles()
|
|
||||||
|
|
||||||
if (!roles) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
return Array.isArray(roles) && roles.includes(role)
|
|
||||||
}
|
|
||||||
|
|
||||||
static async haveAdmin() {
|
|
||||||
return User.haveRole("admin")
|
|
||||||
}
|
|
||||||
|
|
||||||
static async getUserBadges(user_id) {
|
|
||||||
if (!user_id) {
|
|
||||||
user_id = SessionModel.user_id
|
|
||||||
}
|
|
||||||
|
|
||||||
const { data } = await app.cores.api.customRequest({
|
|
||||||
method: "GET",
|
|
||||||
url: `/badge/user/${user_id}`,
|
|
||||||
})
|
|
||||||
|
|
||||||
return data
|
|
||||||
}
|
|
||||||
|
|
||||||
static async changePassword(payload) {
|
|
||||||
const { currentPassword, newPassword } = payload
|
|
||||||
|
|
||||||
const { data } = await app.cores.api.customRequest({
|
|
||||||
method: "POST",
|
|
||||||
url: "/self/update_password",
|
|
||||||
data: {
|
|
||||||
currentPassword,
|
|
||||||
newPassword,
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
return data
|
|
||||||
}
|
|
||||||
|
|
||||||
static async getUserFollowers({
|
|
||||||
user_id,
|
|
||||||
limit = 20,
|
|
||||||
offset = 0,
|
|
||||||
}) {
|
|
||||||
// if user_id or username is not provided, set with current user
|
|
||||||
if (!user_id && !username) {
|
|
||||||
user_id = SessionModel.user_id
|
|
||||||
}
|
|
||||||
|
|
||||||
const { data } = await app.cores.api.customRequest({
|
|
||||||
method: "GET",
|
|
||||||
url: `/user/${user_id}/followers`,
|
|
||||||
params: {
|
|
||||||
limit,
|
|
||||||
offset,
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
return data
|
|
||||||
}
|
|
||||||
|
|
||||||
static async getConnectedUsersFollowing() {
|
|
||||||
const { data } = await app.cores.api.customRequest({
|
|
||||||
method: "GET",
|
|
||||||
url: "/status/connected/following",
|
|
||||||
})
|
|
||||||
|
|
||||||
return data
|
|
||||||
}
|
|
||||||
|
|
||||||
static async checkUsernameAvailability(username) {
|
|
||||||
const { data } = await app.cores.api.customRequest({
|
|
||||||
method: "GET",
|
|
||||||
url: `/user/username_available`,
|
|
||||||
params: {
|
|
||||||
username,
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
return data
|
|
||||||
}
|
|
||||||
|
|
||||||
static async checkEmailAvailability(email) {
|
|
||||||
const { data } = await app.cores.api.customRequest({
|
|
||||||
method: "GET",
|
|
||||||
url: `/user/email_available`,
|
|
||||||
params: {
|
|
||||||
email,
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
return data
|
|
||||||
}
|
|
||||||
}
|
|
@ -74,8 +74,6 @@ export default class Account extends React.Component {
|
|||||||
|
|
||||||
actionsRef = React.createRef()
|
actionsRef = React.createRef()
|
||||||
|
|
||||||
api = window.app.cores.api.withEndpoints()
|
|
||||||
|
|
||||||
componentDidMount = async () => {
|
componentDidMount = async () => {
|
||||||
const token = await SessionModel.getDecodedToken()
|
const token = await SessionModel.getDecodedToken()
|
||||||
const location = window.app.history.location
|
const location = window.app.history.location
|
||||||
|
@ -3,7 +3,6 @@ import * as antd from "antd"
|
|||||||
import jsmediatags from "jsmediatags/dist/jsmediatags.min.js"
|
import jsmediatags from "jsmediatags/dist/jsmediatags.min.js"
|
||||||
|
|
||||||
import PlaylistModel from "models/playlists"
|
import PlaylistModel from "models/playlists"
|
||||||
import FilesModel from "models/files"
|
|
||||||
|
|
||||||
import BasicInformation from "./components/BasicInformation"
|
import BasicInformation from "./components/BasicInformation"
|
||||||
import TracksUploads from "./components/TracksUploads"
|
import TracksUploads from "./components/TracksUploads"
|
||||||
@ -105,7 +104,7 @@ export default class PlaylistCreatorSteps extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
handleUploadTrack = async (req) => {
|
handleUploadTrack = async (req) => {
|
||||||
const response = await FilesModel.uploadFile(req.file, {
|
const response = await app.cores.remoteStorage.uploadFile(req.file, {
|
||||||
timeout: 2000
|
timeout: 2000
|
||||||
}).catch((error) => {
|
}).catch((error) => {
|
||||||
console.error(error)
|
console.error(error)
|
||||||
@ -184,7 +183,7 @@ export default class PlaylistCreatorSteps extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// upload cover file
|
// upload cover file
|
||||||
const result = await FilesModel.uploadFile(file, {
|
const result = await app.cores.remoteStorage.uploadFile(file, {
|
||||||
timeout: 2000
|
timeout: 2000
|
||||||
})
|
})
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user