mirror of
https://github.com/janishutz/MusicPlayerV2.git
synced 2025-11-25 13:04:23 +00:00
Compare commits
1 Commits
e0dcfa6964
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| 576b6f9490 |
@@ -8,7 +8,10 @@
|
||||
<!-- TODO: Make prettier -->
|
||||
</div>
|
||||
<div v-else-if="!$props.isLoggedIn" class="not-logged-in">
|
||||
<p>You are not logged into Apple Music. We therefore can't show you your playlists. <a href="" title="Refreshes the page, allowing you to log in">Change that</a></p>
|
||||
<p>
|
||||
You are not logged into Apple Music. We therefore can't show you your playlists.
|
||||
<a href="" title="Refreshes the page, allowing you to log in">Change that</a>
|
||||
</p>
|
||||
<p>Use the button below to load songs from your local disk</p>
|
||||
<input
|
||||
id="pl-loader"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// These functions handle connections to the backend with socket.io
|
||||
|
||||
import {
|
||||
io, type Socket
|
||||
type Socket, io
|
||||
} from 'socket.io-client';
|
||||
import type {
|
||||
SSEMap
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// These functions handle connections to the backend with socket.io
|
||||
|
||||
import {
|
||||
io, type Socket
|
||||
type Socket, io
|
||||
} from 'socket.io-client';
|
||||
import type {
|
||||
SSEMap
|
||||
@@ -57,7 +57,8 @@ class NotificationHandler {
|
||||
*/
|
||||
connect ( roomName: string, useAntiTamper: boolean ): Promise<void> {
|
||||
return new Promise( ( resolve, reject ) => {
|
||||
fetch( localStorage.getItem( 'url' ) + '/createRoomToken?roomName=' + roomName + '&useAntiTamper=' + useAntiTamper, {
|
||||
fetch( localStorage.getItem( 'url' ) + '/createRoomToken?roomName='
|
||||
+ roomName + '&useAntiTamper=' + useAntiTamper, {
|
||||
'credentials': 'include'
|
||||
} ).then( res => {
|
||||
if ( res.status === 200 ) {
|
||||
@@ -110,7 +111,8 @@ class NotificationHandler {
|
||||
'credentials': 'include'
|
||||
} ).then( res => {
|
||||
if ( res.status === 200 ) {
|
||||
this.eventSource = new EventSource( localStorage.getItem( 'url' ) + '/socket/connection?room=' + this.roomName, {
|
||||
this.eventSource = new EventSource( localStorage.getItem( 'url' )
|
||||
+ '/socket/connection?room=' + this.roomName, {
|
||||
'withCredentials': true
|
||||
} );
|
||||
|
||||
@@ -118,7 +120,8 @@ class NotificationHandler {
|
||||
this.isConnected = true;
|
||||
this.connectionWasSuccessful = true;
|
||||
this.reconnectRetryCount = 0;
|
||||
console.log( '[ SSE Connection ] - ' + new Date().toISOString() + ': Connection successfully established!' );
|
||||
console.log( '[ SSE Connection ] - '
|
||||
+ new Date().toISOString() + ': Connection successfully established!' );
|
||||
resolve();
|
||||
};
|
||||
|
||||
@@ -135,8 +138,10 @@ class NotificationHandler {
|
||||
this.isConnected = false;
|
||||
this.eventSource?.close();
|
||||
this.openConnectionsCount -= 1;
|
||||
console.debug( e );
|
||||
console.log( '[ SSE Connection ] - ' + new Date().toISOString() + ': Reconnecting due to connection error!' );
|
||||
console.debug( '[ SSE Connection ] - Error encountered: ', e );
|
||||
console.log( '[ SSE Connection ] - '
|
||||
+ new Date().toISOString()
|
||||
+ ': Reconnecting due to connection error!' );
|
||||
|
||||
this.eventSource = undefined;
|
||||
|
||||
@@ -146,7 +151,8 @@ class NotificationHandler {
|
||||
}, 1000 * this.reconnectRetryCount );
|
||||
}
|
||||
};
|
||||
} else if ( res.status === 403 || res.status === 401 || res.status === 404 || res.status === 402 ) {
|
||||
} else if ( res.status === 403 || res.status === 401
|
||||
|| res.status === 404 || res.status === 402 ) {
|
||||
document.dispatchEvent( new Event( 'musicplayer:autherror' ) );
|
||||
reject( 'ERR_UNAUTHORIZED' );
|
||||
} else {
|
||||
@@ -158,7 +164,8 @@ class NotificationHandler {
|
||||
reject( 'ERR_ROOM_CONNECTING' );
|
||||
} else {
|
||||
this.openConnectionsCount -= 1;
|
||||
console.log( '[ SSE Connection ] - ' + new Date().toISOString() + ': Reconnecting due to severe connection error!' );
|
||||
console.log( '[ SSE Connection ] - ' + new Date().toISOString()
|
||||
+ ': Reconnecting due to severe connection error!' );
|
||||
|
||||
this.eventSource = undefined;
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ import storeSDK from '@janishutz/store-sdk';
|
||||
import sdk from '@janishutz/login-sdk-server';
|
||||
import sse from './sse';
|
||||
import socket from './socket';
|
||||
import logger from './logger';
|
||||
|
||||
// const isFossVersion = true;
|
||||
//
|
||||
@@ -42,15 +43,13 @@ const run = () => {
|
||||
const httpServer = createServer( app );
|
||||
|
||||
if ( !isFossVersion ) {
|
||||
console.error( '[ APP ] Starting in non-FOSS version' );
|
||||
logger.info( '[ APP ] Starting in non-FOSS version' );
|
||||
|
||||
const storeConfig = JSON.parse( fs.readFileSync( path.join(
|
||||
__dirname,
|
||||
'/config/store-sdk.config.secret.json'
|
||||
) ).toString() );
|
||||
|
||||
console.error( storeConfig );
|
||||
|
||||
storeSDK.configure( storeConfig );
|
||||
|
||||
// ───────────────────────────────────────────────────────────────────
|
||||
@@ -139,6 +138,7 @@ const run = () => {
|
||||
'useAntiTamper': request.query.useAntiTamper === 'true'
|
||||
? true : false,
|
||||
};
|
||||
logger.debug( `Created room "${ roomName }"` );
|
||||
response.send( roomToken );
|
||||
} else {
|
||||
if (
|
||||
@@ -211,7 +211,7 @@ const run = () => {
|
||||
} else {
|
||||
storeSDK.getSubscriptions( uid )
|
||||
.then( stat => {
|
||||
console.error( 'Subscription check was successful' );
|
||||
logger.log( 'Subscription check was successful' );
|
||||
const now = new Date().getTime();
|
||||
|
||||
for ( const sub in stat ) {
|
||||
@@ -232,7 +232,7 @@ const run = () => {
|
||||
resolve( false );
|
||||
} )
|
||||
.catch( e => {
|
||||
console.error( 'Subscription check unsuccessful with error', e );
|
||||
logger.error( 'Subscription check unsuccessful with error', e );
|
||||
reject( 'ERR_NOT_OWNED' );
|
||||
} );
|
||||
}
|
||||
|
||||
104
backend/src/logger.ts
Normal file
104
backend/src/logger.ts
Normal file
@@ -0,0 +1,104 @@
|
||||
import {
|
||||
writeFile
|
||||
} from 'node:fs';
|
||||
|
||||
const log = ( ...msg: string[] ) => {
|
||||
output( 'log', log.caller.toString(), ...msg );
|
||||
};
|
||||
|
||||
const info = ( ...msg: string[] ) => {
|
||||
output( 'info', log.caller.toString(), ...msg );
|
||||
};
|
||||
|
||||
const debug = ( ...msg: string[] ) => {
|
||||
output( 'debug', log.caller.toString(), ...msg );
|
||||
};
|
||||
|
||||
const warn = ( ...msg: string[] ) => {
|
||||
output( 'warn', log.caller.toString(), ...msg );
|
||||
};
|
||||
|
||||
const error = ( ...msg: string[] ) => {
|
||||
output( 'error', log.caller.toString(), ...msg );
|
||||
};
|
||||
|
||||
const fatal = ( ...msg: string[] ) => {
|
||||
output( 'fatal', log.caller.toString(), ...msg );
|
||||
};
|
||||
|
||||
|
||||
let loc = 'stderr';
|
||||
let lev = 0;
|
||||
type LogLevel = 'debug' | 'info' | 'log' | 'warn' | 'error' | 'fatal';
|
||||
const levels = [
|
||||
'debug',
|
||||
'info',
|
||||
'log',
|
||||
'warn',
|
||||
'error',
|
||||
'fatal'
|
||||
];
|
||||
|
||||
const configure = ( location: 'stderr' | 'file', minLevel: LogLevel, file?: string ) => {
|
||||
if ( location === 'file' && !file ) {
|
||||
throw new Error( 'File parameter required when location is "file"' );
|
||||
}
|
||||
|
||||
loc = location === 'stderr' ? 'stderr' : file;
|
||||
lev = levels.indexOf( minLevel );
|
||||
};
|
||||
|
||||
|
||||
const logfile: string[] = [];
|
||||
|
||||
const output = ( level: LogLevel, caller: string, ...message: string[] ) => {
|
||||
if ( levels.indexOf( level ) < lev ) {
|
||||
return;
|
||||
}
|
||||
|
||||
const msg = message.join( ' ' );
|
||||
const out = `[${ level.toUpperCase() }] (${ new Date().toISOString() }) in ${ caller }: ${ msg }`;
|
||||
|
||||
if ( loc === 'stderr' ) {
|
||||
console.error( out );
|
||||
} else {
|
||||
logfile.push( out );
|
||||
save();
|
||||
}
|
||||
};
|
||||
|
||||
let isSaving = false;
|
||||
let waitingOnSave = false;
|
||||
|
||||
const save = () => {
|
||||
if ( isSaving ) {
|
||||
waitingOnSave = true;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
isSaving = true;
|
||||
writeFile( loc, JSON.stringify( logfile ), err => {
|
||||
if ( err )
|
||||
console.error( '[LOGGER] Failed to save with error ' + err );
|
||||
|
||||
if ( waitingOnSave ) {
|
||||
waitingOnSave = false;
|
||||
isSaving = false;
|
||||
save();
|
||||
}
|
||||
|
||||
isSaving = false;
|
||||
} );
|
||||
};
|
||||
|
||||
|
||||
export default {
|
||||
log,
|
||||
info,
|
||||
debug,
|
||||
warn,
|
||||
error,
|
||||
fatal,
|
||||
configure
|
||||
};
|
||||
@@ -4,6 +4,7 @@ import bodyParser from 'body-parser';
|
||||
import {
|
||||
SocketData
|
||||
} from './definitions';
|
||||
import logger from './logger';
|
||||
|
||||
const useSSE = (
|
||||
app: express.Application,
|
||||
@@ -86,7 +87,11 @@ const useSSE = (
|
||||
|
||||
for ( const c in cl ) {
|
||||
if ( cl[ c ] === sid ) {
|
||||
cl.splice( parseInt( c ), 1 );
|
||||
try {
|
||||
cl.splice( parseInt( c ), 1 );
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
} catch ( _ ) { /* empty */ }
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -120,12 +125,13 @@ const useSSE = (
|
||||
( request: express.Request, response: express.Response ) => {
|
||||
if ( request.query.room ) {
|
||||
if ( socketData[ String( request.query.room ) ] ) {
|
||||
logger.debug( `Room "${ request.query.room }" was joined` );
|
||||
response.send( 'ok' );
|
||||
} else {
|
||||
response.status( 404 ).send( 'ERR_ROOM_NOT_FOUND' );
|
||||
}
|
||||
} else {
|
||||
response.status( 404 ).send( 'ERR_NO_ROOM_SPECIFIED' );
|
||||
response.status( 400 ).send( 'ERR_NO_ROOM_SPECIFIED' );
|
||||
}
|
||||
}
|
||||
);
|
||||
@@ -138,8 +144,17 @@ const useSSE = (
|
||||
( request: express.Request, response: express.Response ) => {
|
||||
if ( socketData[ request.body.roomName ] ) {
|
||||
if ( request.body.event === 'tampering' ) {
|
||||
logger.debug( `Room "${
|
||||
request.query.roomName }" has new event: Tampering` );
|
||||
|
||||
const clients = clientReference[ request.body.roomName ];
|
||||
|
||||
if ( !clients ) {
|
||||
response.send( 'ERR_CANNOT_SEND' );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
for ( const client in clients ) {
|
||||
if ( importantClients[ clients[ client ] ] ) {
|
||||
importantClients[ clients[ client ] ]
|
||||
@@ -181,9 +196,18 @@ const useSSE = (
|
||||
.playlistIndex = request.body.data;
|
||||
}
|
||||
|
||||
logger.debug( `Room "${
|
||||
request.query.roomName }" has new event: ${ update }` );
|
||||
|
||||
if ( send ) {
|
||||
const clients = clientReference[ request.body.roomName ];
|
||||
|
||||
if ( !clients ) {
|
||||
response.send( 'ERR_CANNOT_SEND' );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
for ( const client in clients ) {
|
||||
if ( connectedClients[ clients[ client ] ] ) {
|
||||
connectedClients[ clients[ client ] ]
|
||||
@@ -222,9 +246,17 @@ const useSSE = (
|
||||
socketData[ request.body.roomName ].roomToken
|
||||
=== request.body.roomToken
|
||||
) {
|
||||
logger.debug( `Room "${
|
||||
request.query.roomName }" was deleted` );
|
||||
socketData[ request.body.roomName ] = undefined;
|
||||
const clients = clientReference[ request.body.roomName ];
|
||||
|
||||
if ( !clients ) {
|
||||
response.send( 'ok' );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
for ( const client in clients ) {
|
||||
if ( connectedClients[ clients[ client ] ] ) {
|
||||
connectedClients[ clients[ client ] ]
|
||||
@@ -234,6 +266,8 @@ const useSSE = (
|
||||
} ) + '\n\n' );
|
||||
}
|
||||
}
|
||||
|
||||
response.send( 'ok' );
|
||||
} else {
|
||||
response.send( 403 ).send( 'ERR_UNAUTHORIZED' );
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
import path from 'path';
|
||||
import fs from 'fs';
|
||||
import * as sqlDB from './mysqldb.js';
|
||||
import logger from '../logger.js';
|
||||
|
||||
declare let __dirname: string | undefined;
|
||||
|
||||
@@ -33,9 +34,9 @@ dbh.connect();
|
||||
*/
|
||||
const initDB = (): undefined => {
|
||||
( async () => {
|
||||
console.log( '[ DB ] Setting up...' );
|
||||
logger.info( '[ DB ] Setting up...' );
|
||||
dbh.setupDB();
|
||||
console.log( '[ DB ] Setting up complete!' );
|
||||
logger.info( '[ DB ] Setting up complete!' );
|
||||
} )();
|
||||
};
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
import mysql from 'mysql';
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import logger from '../logger';
|
||||
|
||||
declare let __dirname: string | undefined;
|
||||
|
||||
@@ -63,20 +64,20 @@ class SQLDB {
|
||||
const self = this;
|
||||
|
||||
if ( this.isRecovering ) {
|
||||
console.log( '[ SQL ] Attempting to recover from critical error' );
|
||||
logger.info( '[ SQL ] Attempting to recover from critical error' );
|
||||
this.sqlConnection = mysql.createConnection( this.config );
|
||||
this.isRecovering = false;
|
||||
}
|
||||
|
||||
this.sqlConnection.connect( err => {
|
||||
if ( err ) {
|
||||
console.error( '[ SQL ]: An error ocurred whilst connecting: ' + err.stack );
|
||||
logger.error( '[ SQL ]: An error ocurred whilst connecting: ' + err.stack );
|
||||
reject( err );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
console.log( '[ SQL ] Connected to database successfully' );
|
||||
logger.info( '[ SQL ] Connected to database successfully' );
|
||||
self.sqlConnection.on( 'error', err => {
|
||||
if ( err.code === 'ECONNRESET' ) {
|
||||
self.isRecovering = true;
|
||||
@@ -85,7 +86,7 @@ class SQLDB {
|
||||
self.connect();
|
||||
}, 1000 );
|
||||
} else {
|
||||
console.error( err );
|
||||
logger.error( err );
|
||||
}
|
||||
} );
|
||||
resolve( 'connection' );
|
||||
|
||||
Reference in New Issue
Block a user