Yooooomi / your_spotify

Self hosted Spotify tracking dashboard
GNU General Public License v3.0
3.13k stars 126 forks source link

Crashes when calling backend #144

Open s0ftcorn opened 2 years ago

s0ftcorn commented 2 years ago

First time setting this up, knowing a few things about docker, reverse proxies, etc. Whenver i go to https://spotifyauth.NOPE.de/oauth/spotify/callback i get:

Proxy Error
The proxy server received an invalid response from an upstream server.
The proxy server could not handle the request

Reason: Error reading from remote server

And in the logs:

server_1  | [warn]  No user is admin, cannot auto fix database
mongo_spotify | {"t":{"$date":"2022-07-03T00:25:19.098+00:00"},"s":"I",  "c":"NETWORK",  "id":22943,   "ctx":"listener","msg":"Connection accepted","attr":{"remote":"172.30.0.4:53506","connectionId":39,"connectionCount":6}}
mongo_spotify | {"t":{"$date":"2022-07-03T00:25:19.100+00:00"},"s":"I",  "c":"NETWORK",  "id":51800,   "ctx":"conn39","msg":"client metadata","attr":{"remote":"172.30.0.4:53506","client":"conn39","doc":{"driver":{"name":"nodejs|Mongoose","version":"4.5.0"},"os":{"type":"Linux","name":"linux","architecture":"x64","version":"4.19.0-20-amd64"},"platform":"Node.js v16.15.0, LE (unified)","version":"4.5.0|6.3.2"}}}
mongo_spotify | {"t":{"$date":"2022-07-03T00:25:19.110+00:00"},"s":"I",  "c":"NETWORK",  "id":22943,   "ctx":"listener","msg":"Connection accepted","attr":{"remote":"172.30.0.4:53508","connectionId":40,"connectionCount":7}}
mongo_spotify | {"t":{"$date":"2022-07-03T00:25:19.112+00:00"},"s":"I",  "c":"NETWORK",  "id":51800,   "ctx":"conn40","msg":"client metadata","attr":{"remote":"172.30.0.4:53508","client":"conn40","doc":{"driver":{"name":"nodejs|Mongoose","version":"4.5.0"},"os":{"type":"Linux","name":"linux","architecture":"x64","version":"4.19.0-20-amd64"},"platform":"Node.js v16.15.0, LE (unified)","version":"4.5.0|6.3.2"}}}
server_1  | [info]  Starting loop for 0 users
mongo_spotify | {"t":{"$date":"2022-07-03T00:25:25.146+00:00"},"s":"I",  "c":"STORAGE",  "id":22430,   "ctx":"WTCheckpointThread","msg":"WiredTiger message","attr":{"message":"[1656807925:146336][1:0x7f1dc62df700], WT_SESSION.checkpoint: [WT_VERB_CHECKPOINT_PROGRESS] saving checkpoint snapshot min: 3, snapshot max: 3 snapshot count: 0, oldest timestamp: (0, 0) , meta checkpoint timestamp: (0, 0) base write gen: 19"}}
server_1  | node:internal/process/promises:279
server_1  |             triggerUncaughtException(err, true /* fromPromise */);
server_1  |             ^
server_1  | 
server_1  | [UnhandledPromiseRejection: This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). The promise rejected with the reason "AxiosError: Request failed with status code 400".] {
server_1  |   code: 'ERR_UNHANDLED_REJECTION'
server_1  | }
mongo_spotify | {"t":{"$date":"2022-07-03T00:25:27.298+00:00"},"s":"I",  "c":"NETWORK",  "id":22944,   "ctx":"conn39","msg":"Connection ended","attr":{"remote":"172.30.0.4:53506","connectionId":39,"connectionCount":5}}
mongo_spotify | {"t":{"$date":"2022-07-03T00:25:27.298+00:00"},"s":"I",  "c":"NETWORK",  "id":22944,   "ctx":"conn36","msg":"Connection ended","attr":{"remote":"172.30.0.4:53500","connectionId":36,"connectionCount":2}}
mongo_spotify | {"t":{"$date":"2022-07-03T00:25:27.298+00:00"},"s":"I",  "c":"NETWORK",  "id":22944,   "ctx":"conn35","msg":"Connection ended","attr":{"remote":"172.30.0.4:53498","connectionId":35,"connectionCount":1}}
mongo_spotify | {"t":{"$date":"2022-07-03T00:25:27.298+00:00"},"s":"I",  "c":"NETWORK",  "id":22944,   "ctx":"conn38","msg":"Connection ended","attr":{"remote":"172.30.0.4:53504","connectionId":38,"connectionCount":6}}
mongo_spotify | {"t":{"$date":"2022-07-03T00:25:27.298+00:00"},"s":"I",  "c":"NETWORK",  "id":22944,   "ctx":"conn37","msg":"Connection ended","attr":{"remote":"172.30.0.4:53502","connectionId":37,"connectionCount":4}}
mongo_spotify | {"t":{"$date":"2022-07-03T00:25:27.298+00:00"},"s":"I",  "c":"NETWORK",  "id":22944,   "ctx":"conn40","msg":"Connection ended","attr":{"remote":"172.30.0.4:53508","connectionId":40,"connectionCount":3}}
mongo_spotify | {"t":{"$date":"2022-07-03T00:25:27.299+00:00"},"s":"I",  "c":"-",        "id":20883,   "ctx":"conn34","msg":"Interrupted operation as its client disconnected","attr":{"opId":827}}
mongo_spotify | {"t":{"$date":"2022-07-03T00:25:27.301+00:00"},"s":"I",  "c":"NETWORK",  "id":22944,   "ctx":"conn34","msg":"Connection ended","attr":{"remote":"172.30.0.4:53496","connectionId":34,"connectionCount":0}}
server_1  | error Command failed with exit code 1.
server_1  | info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
your_spotify_server_1 exited with code 1

What i thought was going on is the warning about no admin, but since there is no user, i guess i makes sense and is expected upon first time setup.

My docker-compose.yml:

version: "3"

services:
  server:
    image: yooooomi/your_spotify_server
    restart: always
    ports:
      - "8080:8080"
    links:
      - mongo
    depends_on:
      - mongo
    environment:
      - API_ENDPOINT=http://spotifyauth.NOPE.de # This MUST be included as a valid URL in the spotify dashboard
      - CLIENT_ENDPOINT=http://spotify.NOPE.de
      - SPOTIFY_PUBLIC=NOPE
      - SPOTIFY_SECRET=NOPE
      - CORS=http://localhost:3000,http://localhost:3001 # i have no idea what this does lol
      #- MONGO_ENDPOINT=mongodb://mongo:27017/your_spotify

  mongo:
    container_name: mongo_spotify
    image: mongo:4.4.8
    volumes:
      - ./your_spotify_db:/data/db

  web:
    image: yooooomi/your_spotify_client
    restart: always
    ports:
      - "3000:3000"
    environment:
      - API_ENDPOINT=http://spotifyauth.NOPE.de

Im running this behind a basic apache reverse proxy:

<VirtualHost *:80>
        ServerName spotifyauth.NOPE.de
        Redirect permanent / https://spotify.NOPE.de/
</VirtualHost>
<VirtualHost *:443>
ServerName spotifyauth.NOPE.de

SSLEngine On
Include /etc/letsencrypt/options-ssl-apache.conf
SSLCertificateFile /etc/letsencrypt/live/NOPE.de-0001/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/NOPE.de-0001/privkey.pem
ProxyPreserveHost On

RequestHeader set "X-Forwarded-Proto" expr=%{REQUEST_SCHEME}
RequestHeader set "X-Forwarded-SSL" expr=%{HTTPS}
ProxyPass / http://127.0.0.1:8080/
ProxyPassReverse / http://127.0.0.1:8080/

ErrorLog ${APACHE_LOG_DIR}/spotify-error.log
CustomLog ${APACHE_LOG_DIR}/spotify-access.log combined

</VirtualHost>

Config for web looks basically the same only domain and port changed. Any idea whats going on?

Yooooomi commented 2 years ago

Hello! Can you try setting the endpoints in your docker-compose file to use https?

s0ftcorn commented 2 years ago

Had to wipe the data of the database container, but now it works. For one user, specifically my user. Any other gets:

[error]  [AxiosError: Request failed with status code 403] {
  code: 'ERR_BAD_REQUEST',
  config: {
    transitional: {
      silentJSONParsing: true,
      forcedJSONParsing: true,
      clarifyTimeoutError: false
    },
    adapter: [Function: httpAdapter],
    transformRequest: [ [Function: transformRequest] ],
    transformResponse: [ [Function: transformResponse] ],
    timeout: 0,
    xsrfCookieName: 'XSRF-TOKEN',
    xsrfHeaderName: 'X-XSRF-TOKEN',
    maxContentLength: -1,
    maxBodyLength: -1,
    env: { FormData: [Function] },
    validateStatus: [Function: validateStatus],
    headers: {
      Accept: 'application/json, text/plain, */*',
      'Content-Type': 'application/x-www-form-urlencoded',
      Authorization: 'Bearer NOPE?',
      'User-Agent': 'axios/0.27.2'
    },
    baseURL: 'https://api.spotify.com/v1',
    method: 'get',
    url: '/me',
    data: undefined
  },
  request: <ref *1> ClientRequest {
    _events: [Object: null prototype] {
      abort: [Function (anonymous)],
      aborted: [Function (anonymous)],
      connect: [Function (anonymous)],
      error: [Function (anonymous)],
      socket: [Function (anonymous)],
      timeout: [Function (anonymous)],
      prefinish: [Function: requestOnPrefinish]
    },
    _eventsCount: 7,
    _maxListeners: undefined,
    outputData: [],
    outputSize: 0,
    writable: true,
    destroyed: false,
    _last: true,
    chunkedEncoding: false,
    shouldKeepAlive: false,
    maxRequestsOnConnectionReached: false,
    _defaultKeepAlive: true,
    useChunkedEncodingByDefault: false,
    sendDate: false,
    _removedConnection: false,
    _removedContLen: false,
    _removedTE: false,
    _contentLength: 0,
    _hasBody: true,
    _trailer: '',
    finished: true,
    _headerSent: true,
    _closed: false,
    socket: TLSSocket {
      _tlsOptions: [Object],
      _secureEstablished: true,
      _securePending: false,
      _newSessionPending: false,
      _controlReleased: true,
      secureConnecting: false,
      _SNICallback: null,
      servername: 'api.spotify.com',
      alpnProtocol: false,
      authorized: true,
      authorizationError: null,
      encrypted: true,
      _events: [Object: null prototype],
      _eventsCount: 10,
      connecting: false,
      _hadError: false,
      _parent: null,
      _host: 'api.spotify.com',
      _readableState: [ReadableState],
      _maxListeners: undefined,
      _writableState: [WritableState],
      allowHalfOpen: false,
      _sockname: null,
      _pendingData: null,
      _pendingEncoding: '',
      server: undefined,
      _server: null,
      ssl: [TLSWrap],
      _requestCert: true,
      _rejectUnauthorized: true,
      parser: null,
      _httpMessage: [Circular *1],
      [Symbol(res)]: [TLSWrap],
      [Symbol(verified)]: true,
      [Symbol(pendingSession)]: null,
      [Symbol(async_id_symbol)]: 378610,
      [Symbol(kHandle)]: [TLSWrap],
      [Symbol(lastWriteQueueSize)]: 0,
      [Symbol(timeout)]: null,
      [Symbol(kBuffer)]: null,
      [Symbol(kBufferCb)]: null,
      [Symbol(kBufferGen)]: null,
      [Symbol(kCapture)]: false,
      [Symbol(kSetNoDelay)]: false,
      [Symbol(kSetKeepAlive)]: true,
      [Symbol(kSetKeepAliveInitialDelay)]: 60,
      [Symbol(kBytesRead)]: 0,
      [Symbol(kBytesWritten)]: 0,
      [Symbol(connect-options)]: [Object],
      [Symbol(RequestTimeout)]: undefined
    },
    _header: 'GET /v1/me HTTP/1.1\r\n' +
      'Accept: application/json, text/plain, */*\r\n' +
      'Content-Type: application/x-www-form-urlencoded\r\n' +
      'Authorization: Bearer NOPE\r\n' +
      'User-Agent: axios/0.27.2\r\n' +
      'Host: api.spotify.com\r\n' +
      'Connection: close\r\n' +
      '\r\n',
    _keepAliveTimeout: 0,
    _onPendingData: [Function: nop],
    agent: Agent {
      _events: [Object: null prototype],
      _eventsCount: 2,
      _maxListeners: undefined,
      defaultPort: 443,
      protocol: 'https:',
      options: [Object: null prototype],
      requests: [Object: null prototype] {},
      sockets: [Object: null prototype],
      freeSockets: [Object: null prototype] {},
      keepAliveMsecs: 1000,
      keepAlive: false,
      maxSockets: Infinity,
      maxFreeSockets: 256,
      scheduling: 'lifo',
      maxTotalSockets: Infinity,
      totalSocketCount: 1,
      maxCachedSessions: 100,
      _sessionCache: [Object],
      [Symbol(kCapture)]: false
    },
    socketPath: undefined,
    method: 'GET',
    maxHeaderSize: undefined,
    insecureHTTPParser: undefined,
    path: '/v1/me',
    _ended: true,
    res: IncomingMessage {
      _readableState: [ReadableState],
      _events: [Object: null prototype],
      _eventsCount: 4,
      _maxListeners: undefined,
      socket: [TLSSocket],
      httpVersionMajor: 1,
      httpVersionMinor: 1,
      httpVersion: '1.1',
      complete: true,
      rawHeaders: [Array],
      rawTrailers: [],
      aborted: false,
      upgrade: false,
      url: '',
      method: null,
      statusCode: 403,
      statusMessage: 'Forbidden',
      client: [TLSSocket],
      _consuming: false,
      _dumped: false,
      req: [Circular *1],
      responseUrl: 'https://api.spotify.com/v1/me',
      redirects: [],
      [Symbol(kCapture)]: false,
      [Symbol(kHeaders)]: [Object],
      [Symbol(kHeadersCount)]: 30,
      [Symbol(kTrailers)]: null,
      [Symbol(kTrailersCount)]: 0,
      [Symbol(RequestTimeout)]: undefined
    },
    aborted: false,
    timeoutCb: null,
    upgradeOrConnect: false,
    parser: null,
    maxHeadersCount: null,
    reusedSocket: false,
    host: 'api.spotify.com',
    protocol: 'https:',
    _redirectable: Writable {
      _writableState: [WritableState],
      _events: [Object: null prototype],
      _eventsCount: 3,
      _maxListeners: undefined,
      _options: [Object],
      _ended: true,
      _ending: true,
      _redirectCount: 0,
      _redirects: [],
      _requestBodyLength: 0,
      _requestBodyBuffers: [],
      _onNativeResponse: [Function (anonymous)],
      _currentRequest: [Circular *1],
      _currentUrl: 'https://api.spotify.com/v1/me',
      [Symbol(kCapture)]: false
    },
    [Symbol(kCapture)]: false,
    [Symbol(kNeedDrain)]: false,
    [Symbol(corked)]: 0,
    [Symbol(kOutHeaders)]: [Object: null prototype] {
      accept: [Array],
      'content-type': [Array],
      authorization: [Array],
      'user-agent': [Array],
      host: [Array]
    }
  },
  response: {
    status: 403,
    statusText: 'Forbidden',
    headers: {
      'cache-control': 'private, max-age=0',
      'access-control-allow-origin': '*',
      'access-control-allow-headers': 'Accept, App-Platform, Authorization, Content-Type, Origin, Retry-After, Spotify-App-Version, X-Cloud-Trace-Context, client-token, content-access-token',
      'access-control-allow-methods': 'GET, POST, OPTIONS, PUT, DELETE, PATCH',
      'access-control-allow-credentials': 'true',
      'access-control-max-age': '604800',
      'content-length': '46',
      'strict-transport-security': 'max-age=31536000',
      'x-content-type-options': 'nosniff',
      vary: 'Accept-Encoding',
      date: 'Sun, 03 Jul 2022 19:59:05 GMT',
      server: 'envoy',
      via: 'HTTP/2 edgeproxy, 1.1 google',
      'alt-svc': 'h3=":443"; ma=2592000,h3-29=":443"; ma=2592000',
      connection: 'close'
    },
    config: {
      transitional: [Object],
      adapter: [Function: httpAdapter],
      transformRequest: [Array],
      transformResponse: [Array],
      timeout: 0,
      xsrfCookieName: 'XSRF-TOKEN',
      xsrfHeaderName: 'X-XSRF-TOKEN',
      maxContentLength: -1,
      maxBodyLength: -1,
      env: [Object],
      validateStatus: [Function: validateStatus],
      headers: [Object],
      baseURL: 'https://api.spotify.com/v1',
      method: 'get',
      url: '/me',
      data: undefined
    },
    request: <ref *1> ClientRequest {
      _events: [Object: null prototype],
      _eventsCount: 7,
      _maxListeners: undefined,
      outputData: [],
      outputSize: 0,
      writable: true,
      destroyed: false,
      _last: true,
      chunkedEncoding: false,
      shouldKeepAlive: false,
      maxRequestsOnConnectionReached: false,
      _defaultKeepAlive: true,
      useChunkedEncodingByDefault: false,
      sendDate: false,
      _removedConnection: false,
      _removedContLen: false,
      _removedTE: false,
      _contentLength: 0,
      _hasBody: true,
      _trailer: '',
      finished: true,
      _headerSent: true,
      _closed: false,
      socket: [TLSSocket],
      _header: 'GET /v1/me HTTP/1.1\r\n' +
        'Accept: application/json, text/plain, */*\r\n' +
        'Content-Type: application/x-www-form-urlencoded\r\n' +
        'Authorization: Bearer NOPE\r\n' +
        'User-Agent: axios/0.27.2\r\n' +
        'Host: api.spotify.com\r\n' +
        'Connection: close\r\n' +
        '\r\n',
      _keepAliveTimeout: 0,
      _onPendingData: [Function: nop],
      agent: [Agent],
      socketPath: undefined,
      method: 'GET',
      maxHeaderSize: undefined,
      insecureHTTPParser: undefined,
      path: '/v1/me',
      _ended: true,
      res: [IncomingMessage],
      aborted: false,
      timeoutCb: null,
      upgradeOrConnect: false,
      parser: null,
      maxHeadersCount: null,
      reusedSocket: false,
      host: 'api.spotify.com',
      protocol: 'https:',
      _redirectable: [Writable],
      [Symbol(kCapture)]: false,
      [Symbol(kNeedDrain)]: false,
      [Symbol(corked)]: 0,
      [Symbol(kOutHeaders)]: [Object: null prototype]
    },
    data: 'User not registered in the Developer Dashboard'
  }
}
Yooooomi commented 2 years ago

I think the error you're getting is not related to the implementation but rather how you logged in your accounts. Someone had a similar problem here https://github.com/JohnnyCrazy/SpotifyAPI-NET/issues/700

s0ftcorn commented 2 years ago

If i read correctly this would only be the case if the person logging in has multiple accounts. In this case basically any user that tries to login with their spotify account, gets asked to trust this app, they say yes aaaand they are back to the login screen of y_s The users i asked to try it all had only one spotify account. A few of these were facebook accounts that are linked to their spotify, which shouldnt matter?

Yooooomi commented 2 years ago

It looks like a recent error. The flow is implemented correctly in y_s...

Yooooomi commented 2 years ago

Hello, any news on this one?

s0ftcorn commented 2 years ago

Issue persists. Though i didnt investigate further.

meanii commented 1 year ago

i had to add Users's email in my dev console of spotify, then they logged in

Yooooomi commented 1 year ago

Hello, any news?

s0ftcorn commented 1 year ago

Hi!

Sorry for the late response. Quickly tried with a friend and the issue persists.

Yooooomi commented 1 year ago

Hi! Can you try omitting the cors value in your docker compose?

s0ftcorn commented 1 year ago

Commented that out: - CORS=all and it changes nothing. i.e. the same error.