From c7b9b214b72f42a9865e8f52b8e9b578286b2ea6 Mon Sep 17 00:00:00 2001 From: Eclypsed Date: Fri, 23 Feb 2024 00:53:54 -0500 Subject: [PATCH] FINALLY, Beautiful connection types! --- src/app.d.ts | 61 ++++++------ src/hooks.server.ts | 8 +- src/lib/components/media/mediaCard.svelte | 1 - src/lib/server/users.db | Bin 24576 -> 0 bytes src/lib/server/users.ts | 94 +++++++++--------- src/lib/service-managers/youtubeMusic.ts | 3 - src/lib/services.json | 14 --- .../jellyfin.ts => services.ts} | 75 +++++++++++--- src/routes/api/connections/+server.ts | 15 ++- .../[connectionId]/info/+server.ts | 53 ---------- .../api/users/[userId]/connections/+server.ts | 12 +++ .../users/[userId]/recommendations/+server.ts | 8 +- src/routes/login/+page.server.ts | 2 +- .../settings/connections/+page.server.ts | 24 ++--- src/routes/settings/connections/+page.svelte | 18 ++-- .../connections/connectionProfile.svelte | 26 ++--- 16 files changed, 200 insertions(+), 214 deletions(-) delete mode 100644 src/lib/service-managers/youtubeMusic.ts delete mode 100644 src/lib/services.json rename src/lib/{service-managers/jellyfin.ts => services.ts} (56%) delete mode 100644 src/routes/api/connections/[connectionId]/info/+server.ts diff --git a/src/app.d.ts b/src/app.d.ts index dc4548d..34d0485 100644 --- a/src/app.d.ts +++ b/src/app.d.ts @@ -4,7 +4,7 @@ declare global { namespace App { // interface Error {} interface Locals { - user: Omit + user: Omit } // interface PageData {} // interface PageState {} @@ -21,25 +21,12 @@ declare global { interface User { id: string username: string - password: string + passwordHash: string } type serviceType = 'jellyfin' | 'youtube-music' - type Service = Jellyfin.Service | YouTubeMusic.Service - - type Tokens = T extends Jellyfin.Service ? Jellyfin.Tokens : T extends YouTubeMusic.Service ? YouTubeMusic.Tokens : {} - - // type ServiceTokenPair = [Jellyfin.Service, Jellyfin.Tokens] | [YouTubeMusic.Service, YouTubeMusic.Tokens] - - interface BaseConnection { - id: string - userId: string - type: T extends Jellyfin.Service ? 'jellyfin' : T extends YouTubeMusic.Service ? 'youtube-music' : serviceType - service: T extends undefined ? Service : T - } - - type Connection = BaseConnection & Tokens + type Connection = T extends 'jellyfin' ? Jellyfin.Connection : T extends 'youtube-music' ? YouTubeMusic.Connection : never // 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. @@ -94,15 +81,19 @@ declare global { // The jellyfin API will not always return the data it says it will, for example /Users/AuthenticateByName says it will // retrun the ServerName, it wont. This must be fetched from /System/Info. // So, ONLY DEFINE THE INTERFACES FOR DATA THAT IS GARUNTEED TO BE RETURNED (unless the data value itself is inherently optional) - interface Service { + interface Connection { + id: string userId: string - urlOrigin: string - username?: string - serverName?: string - } - - interface Tokens { - accessToken: string + type: 'jellyfin' + service: { + userId: string + urlOrigin: string + username?: string + serverName?: string + } + tokens: { + accessToken: string + } } interface User { @@ -171,16 +162,20 @@ declare global { } namespace YouTubeMusic { - interface Service { + interface Connection { + id: string userId: string - username?: string - profilePicture?: string - } - - interface Tokens { - accessToken: string - refreshToken: string - expiry: number + type: 'youtube-music' + service: { + userId: string + username?: string + profilePicture?: string + } + tokens: { + accessToken: string + refreshToken: string + expiry: number + } } } } diff --git a/src/hooks.server.ts b/src/hooks.server.ts index 450b6bf..006571f 100644 --- a/src/hooks.server.ts +++ b/src/hooks.server.ts @@ -17,7 +17,7 @@ export const handle: Handle = async ({ event, resolve }) => { if (!authToken) throw redirect(303, `/login?redirect=${urlpath}`) try { - const tokenData = jwt.verify(authToken, SECRET_JWT_KEY) as Omit + const tokenData = jwt.verify(authToken, SECRET_JWT_KEY) as Omit event.locals.user = tokenData } catch { throw redirect(303, `/login?redirect=${urlpath}`) @@ -33,7 +33,7 @@ export const handleFetch: HandleFetch = async ({ request, fetch, event }) => { if (event.locals.user) { const expiredConnection = Connections.getExpiredConnections(event.locals.user.id) for (const connection of expiredConnection) { - switch (connection.service.type) { + switch (connection.type) { case 'youtube-music': // Again DON'T SHIP THIS, CLIENT SECRET SHOULD NOT BE EXPOSED TO USERS const response = await fetch('https://oauth2.googleapis.com/token', { @@ -41,13 +41,13 @@ export const handleFetch: HandleFetch = async ({ request, fetch, event }) => { body: JSON.stringify({ client_id: PUBLIC_YOUTUBE_API_CLIENT_ID, client_secret: YOUTUBE_API_CLIENT_SECRET, - refresh_token: connection.refreshToken as string, + refresh_token: connection.tokens.refreshToken as string, grant_type: 'refresh_token', }), }) const { access_token, expires_in } = await response.json() const newExpiry = Date.now() + expires_in * 1000 - Connections.updateTokens(connection.id, access_token, connection.refreshToken, newExpiry) + Connections.updateTokens(connection.id, access_token, connection.tokens.refreshToken, newExpiry) console.log('Refreshed YouTubeMusic access token') } } diff --git a/src/lib/components/media/mediaCard.svelte b/src/lib/components/media/mediaCard.svelte index 6fa8ddd..2134641 100644 --- a/src/lib/components/media/mediaCard.svelte +++ b/src/lib/components/media/mediaCard.svelte @@ -1,7 +1,6 @@
-
- {serviceData.displayName} icon +
+ {reactiveServiceData.displayName} icon {#if 'profilePicture' in connection.service && typeof connection.service.profilePicture === 'string'} - + {/if}
Username
- {serviceData.displayName} + {reactiveServiceData.displayName} {#if 'serverName' in connection.service} - {connection.service.serverName} {/if}
-
- showModal = !showModal}> +
+ (showModal = !showModal)}> {#if showModal} -
-