Added support for reverse proxy and routing managed by vue

Use --locationbase to specify the path used by the reverse proxy
Updated deezer-js to 1.3.8
This commit is contained in:
RemixDev 2022-07-30 00:23:48 +02:00
parent 2a32e772dd
commit cb8ab5cfae
No known key found for this signature in database
GPG Key ID: B33962B465BDB51C
7 changed files with 53 additions and 6 deletions

View File

@ -30,6 +30,7 @@
"@types/cookie-parser": "1.4.2", "@types/cookie-parser": "1.4.2",
"@types/dateformat": "5.0.0", "@types/dateformat": "5.0.0",
"@types/debug": "4.1.5", "@types/debug": "4.1.5",
"@types/ejs": "3.1.1",
"@types/express": "4.17.11", "@types/express": "4.17.11",
"@types/express-session": "^1.17.3", "@types/express-session": "^1.17.3",
"@types/morgan": "1.9.2", "@types/morgan": "1.9.2",
@ -45,6 +46,7 @@
"deemix": "^3.6.0", "deemix": "^3.6.0",
"deezer-js": "^1.3.0", "deezer-js": "^1.3.0",
"dotenv": "8.2.0", "dotenv": "8.2.0",
"ejs": "3.1.8",
"express": "4.17.1", "express": "4.17.1",
"express-session": "^1.17.1", "express-session": "^1.17.1",
"memorystore": "1.6.6", "memorystore": "1.6.6",

View File

@ -11,14 +11,16 @@ if (!isModule) {
const argv = yargs(hideBin(process.argv)).options({ const argv = yargs(hideBin(process.argv)).options({
port: { type: 'string', default: '6595' }, port: { type: 'string', default: '6595' },
host: { type: 'string', default: '127.0.0.1' }, host: { type: 'string', default: '127.0.0.1' },
locationbase: { type: 'string', default: '/' },
singleuser: { type: 'boolean', default: false } singleuser: { type: 'boolean', default: false }
}).argv as Arguments }).argv as Arguments
const DEEMIX_SERVER_PORT = process.env.DEEMIX_SERVER_PORT ?? argv.port const DEEMIX_SERVER_PORT = process.env.DEEMIX_SERVER_PORT ?? argv.port
const DEEMIX_HOST = process.env.DEEMIX_HOST ?? argv.host const DEEMIX_HOST = process.env.DEEMIX_HOST ?? argv.host
const DEEMIX_LOCATION_BASE = process.env.DEEMIX_LOCATION_BASE ?? argv.locationbase
const IS_SINGLE_USER = !!process.env.DEEMIX_SINGLE_USER ?? !!argv.singleuser const IS_SINGLE_USER = !!process.env.DEEMIX_SINGLE_USER ?? !!argv.singleuser
const server = new DeemixServer(DEEMIX_HOST, DEEMIX_SERVER_PORT, IS_SINGLE_USER) const server = new DeemixServer(DEEMIX_HOST, DEEMIX_SERVER_PORT, DEEMIX_LOCATION_BASE, IS_SINGLE_USER)
server.init() server.init()
} }

View File

@ -5,7 +5,7 @@ import deleteEndpoints from './delete'
import postEndpoints from './post' import postEndpoints from './post'
import patchEndpoints from './patch' import patchEndpoints from './patch'
const prependApiPath = (path: string) => `/api${path}` const prependApiPath = (path: string) => `*/api${path}`
interface Method { interface Method {
method: string method: string
@ -40,7 +40,7 @@ export function registerApis(app: Application) {
}) })
// Fallback, for SPA mode // Fallback, for SPA mode
app.get('*', (_, res) => { app.get('*/api*', (_, res) => {
res.redirect('/') res.send({ error: "API endpoint doesn't exist" })
}) })
} }

View File

@ -1,5 +1,8 @@
import http, { Server } from 'http' import http, { Server } from 'http'
import path from 'path'
import fs from 'fs'
import express, { Application } from 'express' import express, { Application } from 'express'
import ejs from 'ejs'
import { Server as WsServer, OPEN as WsOpen } from 'ws' import { Server as WsServer, OPEN as WsOpen } from 'ws'
import initDebug from 'debug' import initDebug from 'debug'
// @ts-expect-error // @ts-expect-error
@ -14,10 +17,12 @@ import { loadLoginCredentials } from './helpers/loginStorage'
import { Port, Listener } from './types' import { Port, Listener } from './types'
import { DeemixApp } from './app' import { DeemixApp } from './app'
import { normalizePort } from './helpers/port' import { normalizePort } from './helpers/port'
import { WEBUI_DIR } from './helpers/paths'
export class DeemixServer { export class DeemixServer {
host: string host: string
port: Port port: Port
locationBase: string
isSingleUser: boolean isSingleUser: boolean
wss: WsServer wss: WsServer
@ -25,9 +30,10 @@ export class DeemixServer {
server: Server server: Server
deemixApp: DeemixApp deemixApp: DeemixApp
constructor(host: string, port: string, singleuser: boolean = false) { constructor(host: string, port: string, locationBase: string, singleuser: boolean = false) {
this.host = host this.host = host
this.port = normalizePort(port) this.port = normalizePort(port)
this.locationBase = locationBase
this.isSingleUser = singleuser this.isSingleUser = singleuser
this.wss = new WsServer({ noServer: true }) this.wss = new WsServer({ noServer: true })
@ -65,6 +71,29 @@ export class DeemixServer {
/* === APIs === */ /* === APIs === */
registerApis(this.app) registerApis(this.app)
/* === Fallback === */
this.app.get('*/favicon.ico', (_, res) => {
res.sendFile(path.join(WEBUI_DIR, 'favicon.ico'))
})
this.app.get('*/js/*', (req, res) => {
const link = req.url.substr(req.url.indexOf('/js/'))
res.sendFile(path.join(WEBUI_DIR, link))
})
this.app.get('*/fonts/*', (req, res) => {
const link = req.url.substr(req.url.indexOf('/fonts/'))
res.sendFile(path.join(WEBUI_DIR, link))
})
this.app.get('*/res/*', (req, res) => {
const link = req.url.substr(req.url.indexOf('/res/'))
res.sendFile(path.join(WEBUI_DIR, link))
})
this.app.get('*', (req, res) => {
console.log(req.url)
fs.readFile(path.join(WEBUI_DIR, 'index.ejs'), (_, html) => {
res.send(ejs.render(html.toString(), { locationBase: this.locationBase }))
})
})
/* === Config === */ /* === Config === */
this.app.set('port', this.port) this.app.set('port', this.port)

View File

@ -235,6 +235,8 @@ export interface GetAlbumResponse extends BaseDeezerObject, CoveredDeezerObject
export interface Arguments { export interface Arguments {
port: string port: string
host: string host: string
locationbase: string
singleuser: boolean
[x: string]: unknown [x: string]: unknown
$0: string $0: string

View File

@ -728,6 +728,11 @@
resolved "https://registry.yarnpkg.com/@types/debug/-/debug-4.1.5.tgz#b14efa8852b7768d898906613c23f688713e02cd" resolved "https://registry.yarnpkg.com/@types/debug/-/debug-4.1.5.tgz#b14efa8852b7768d898906613c23f688713e02cd"
integrity sha512-Q1y515GcOdTHgagaVFhHnIFQ38ygs/kmxdNpvpou+raI9UO3YZcHDngBSYKQklcKlvA7iuQlmIKbzvmxcOE9CQ== integrity sha512-Q1y515GcOdTHgagaVFhHnIFQ38ygs/kmxdNpvpou+raI9UO3YZcHDngBSYKQklcKlvA7iuQlmIKbzvmxcOE9CQ==
"@types/ejs@3.1.1":
version "3.1.1"
resolved "https://registry.yarnpkg.com/@types/ejs/-/ejs-3.1.1.tgz#29c539826376a65e7f7d672d51301f37ed718f6d"
integrity sha512-RQul5wEfY7BjWm0sYY86cmUN/pcXWGyVxWX93DFFJvcrxax5zKlieLwA3T77xJGwNcZW0YW6CYG70p1m8xPFmA==
"@types/eslint-scope@^3.7.0": "@types/eslint-scope@^3.7.0":
version "3.7.4" version "3.7.4"
resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.4.tgz#37fc1223f0786c39627068a12e94d6e6fc61de16" resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.4.tgz#37fc1223f0786c39627068a12e94d6e6fc61de16"
@ -2354,6 +2359,13 @@ ee-first@1.1.1:
resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d"
integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==
ejs@3.1.8:
version "3.1.8"
resolved "https://registry.yarnpkg.com/ejs/-/ejs-3.1.8.tgz#758d32910c78047585c7ef1f92f9ee041c1c190b"
integrity sha512-/sXZeMlhS0ArkfX2Aw780gJzXSMPnKjtspYZv+f3NiKLlubezAHDU5+9xz6gd3/NhG3txQCo6xlglmTS+oTGEQ==
dependencies:
jake "^10.8.5"
electron-to-chromium@^1.4.202: electron-to-chromium@^1.4.202:
version "1.4.206" version "1.4.206"
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.206.tgz#580ff85b54d7ec0c05f20b1e37ea0becdd7b0ee4" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.206.tgz#580ff85b54d7ec0c05f20b1e37ea0becdd7b0ee4"

2
webui

@ -1 +1 @@
Subproject commit c6912a395c778a325f2633e130cef82cea55cc9d Subproject commit 4854f2a108648473030b5306a1ab585fcc411d20