diff --git a/src/app.d.ts b/src/app.d.ts index cad46de..a1e9f5e 100644 --- a/src/app.d.ts +++ b/src/app.d.ts @@ -45,6 +45,12 @@ declare global { tokens: Tokens } + interface ConnectionInfo { + connectionId: string + serviceType: serviceType + username: string + } + // These Schemas should only contain general info data that is necessary for data fetching purposes. // They are NOT meant to be stores for large amounts of data, i.e. Don't include the data for every single song the Playlist type. // Big data should be fetched as needed in the app, these exist to ensure that the info necessary to fetch that data is there. @@ -111,9 +117,9 @@ declare global { tokens: JFTokens } - interface AccountInfo { - username: string - servername?: string + interface JFConnectionInfo extends ConnectionInfo { + serviceType: 'jellyfin' + servername: string } interface AuthData { @@ -199,8 +205,8 @@ declare global { tokens: YTTokens } - interface AccountInfo { - username: string + interface YTConnectionInfo extends ConnectionInfo { + serviceType: 'youtube-music' profilePicture?: string } } diff --git a/src/lib/server/users.db b/src/lib/server/users.db index c1dfafc..b050acc 100644 Binary files a/src/lib/server/users.db and b/src/lib/server/users.db differ diff --git a/src/routes/api/users/[userId]/connectionInfo/+server.ts b/src/routes/api/users/[userId]/connectionInfo/+server.ts new file mode 100644 index 0000000..0a55391 --- /dev/null +++ b/src/routes/api/users/[userId]/connectionInfo/+server.ts @@ -0,0 +1,60 @@ +import type { RequestHandler } from '@sveltejs/kit' +import { Connections } from '$lib/server/users' +import { google } from 'googleapis' + +const jellyfinInfo = async (connection: Jellyfin.JFConnection): Promise => { + const reqHeaders = new Headers({ Authorization: `MediaBrowser Token="${connection.tokens.accessToken}"` }) + + const userUrl = new URL(`Users/${connection.service.userId}`, connection.service.urlOrigin).href + const systemUrl = new URL('System/Info', connection.service.urlOrigin).href + + const userResponse = await fetch(userUrl, { headers: reqHeaders }) + const systemResponse = await fetch(systemUrl, { headers: reqHeaders }) + + const userData: Jellyfin.User = await userResponse.json() + const systemData: Jellyfin.System = await systemResponse.json() + + return { + connectionId: connection.id, + serviceType: 'jellyfin', + username: userData.Name, + servername: systemData.ServerName, + } +} + +const youtubeInfo = async (connection: YouTubeMusic.YTConnection): Promise => { + const youtube = google.youtube('v3') + const userChannelResponse = await youtube.channels.list({ mine: true, part: ['snippet'], access_token: connection.tokens.accessToken }) + const userChannel = userChannelResponse.data.items![0] + + return { + connectionId: connection.id, + serviceType: connection.service.type, + username: userChannel.snippet?.title as string, + profilePicture: userChannel.snippet?.thumbnails?.default?.url as string | undefined, + } +} + +export const GET: RequestHandler = async ({ params, url }) => { + const userId = params.userId as string + const requestedConnectionIds = url.searchParams.get('connectionIds')?.split(',') + + const connectionInfo: ConnectionInfo[] = [] + + const userConnections: Connection[] = requestedConnectionIds ? Array.from(requestedConnectionIds, (id) => Connections.getConnection(id)) : Connections.getUserConnections(userId) + + for (const connection of userConnections) { + let info: ConnectionInfo + switch (connection.service.type) { + case 'jellyfin': + info = await jellyfinInfo(connection as Jellyfin.JFConnection) + break + case 'youtube-music': + info = await youtubeInfo(connection as YouTubeMusic.YTConnection) + break + } + connectionInfo.push(info) + } + + return Response.json({ connectionInfo }) +} diff --git a/src/routes/settings/connections/+page.server.ts b/src/routes/settings/connections/+page.server.ts index 2ba1d9f..bac692a 100644 --- a/src/routes/settings/connections/+page.server.ts +++ b/src/routes/settings/connections/+page.server.ts @@ -10,6 +10,7 @@ export const load: PageServerLoad = async ({ fetch, locals }) => { headers: { apikey: SECRET_INTERNAL_API_KEY }, }) + console.log(locals.user.id) const userConnections: Connection[] = await connectionsResponse.json() return { userConnections } } @@ -37,23 +38,10 @@ export const actions: Actions = { const authData: Jellyfin.AuthData = await jellyfinAuthResponse.json() - const userUrl = new URL(`Users/${authData.User.Id}`, serverUrl.toString()).href - const systemUrl = new URL('System/Info', serverUrl.toString()).href - - const reqHeaders = new Headers({ Authorization: `MediaBrowser Token="${authData.AccessToken}"` }) - - const userResponse = await fetch(userUrl, { headers: reqHeaders }) - const systemResponse = await fetch(systemUrl, { headers: reqHeaders }) - - const userData: Jellyfin.User = await userResponse.json() - const systemData: Jellyfin.System = await systemResponse.json() - const serviceData: Jellyfin.JFService = { type: 'jellyfin', userId: authData.User.Id, - // username: userData.Name, urlOrigin: serverUrl.toString(), - // serverName: systemData.ServerName, } const tokenData: Jellyfin.JFTokens = { accessToken: authData.AccessToken, @@ -89,9 +77,7 @@ export const actions: Actions = { const serviceData: YouTubeMusic.YTService = { type: 'youtube-music', userId: userChannel.id as string, - // username: userChannel.snippet?.title as string, urlOrigin: 'https://www.googleapis.com/youtube/v3', - // profilePicture: userChannel.snippet?.thumbnails?.default?.url as string | undefined, } const newConnectionResponse = await fetch(`/api/users/${locals.user.id}/connections`, {