From cd11730d898dedef877c59c78031b30b596bed6a Mon Sep 17 00:00:00 2001 From: Isaac Hunter Date: Thu, 19 Sep 2024 23:55:33 -0400 Subject: [PATCH] create api for refreshing spotify access token --- docker-compose.network.yml | 4 ++-- proxy/default.conf.tpl | 3 ++- server/controllers/groupController.ts | 9 ++++++++- server/docs/swagger_output.json | 2 +- server/models/spotifyAuthModel.ts | 10 +++++++++- server/services/spotifyService.ts | 6 +++++- server/views/userViews.ts | 7 +++++-- 7 files changed, 32 insertions(+), 9 deletions(-) diff --git a/docker-compose.network.yml b/docker-compose.network.yml index 2046e55..8cb41ad 100644 --- a/docker-compose.network.yml +++ b/docker-compose.network.yml @@ -3,8 +3,8 @@ services: restart: always build: context: . - dockerfile: ./server.Dockerfile - # dockerfile: ./server/Dockerfile + # dockerfile: ./server.Dockerfile + dockerfile: ./server/Dockerfile container_name: server-jbx environment: - NODE_ENV=network diff --git a/proxy/default.conf.tpl b/proxy/default.conf.tpl index c23d6d3..59e5d90 100644 --- a/proxy/default.conf.tpl +++ b/proxy/default.conf.tpl @@ -25,7 +25,8 @@ server { proxy_set_header X-Forwarded-For "$proxy_add_x_forwarded_for"; proxy_set_header Token "$http_token"; - proxy_pass_header Token; + proxy_pass_header Token; + proxy_pass_header Authorization; } location /socket.io { diff --git a/server/controllers/groupController.ts b/server/controllers/groupController.ts index 1b3e38a..ee9baf6 100644 --- a/server/controllers/groupController.ts +++ b/server/controllers/groupController.ts @@ -28,10 +28,17 @@ export const assignSpotifyToGroup = async ( return group } -export const getGroupSpotifyAuth = async (groupId) => { +export const getGroupSpotifyAuth = async (groupId: string) => { const group = await getOrError(groupId, Group) const auth = await getOrError(group.spotifyAuthId?.toString() ?? '', SpotifyAuth) + if (auth.isExpired()) { + const spotify = await SpotifyService.connect(auth.spotifyEmail) + const updatedAccessToken = await spotify.getAccessToken() + auth.accessToken = updatedAccessToken + auth.save() + } + return auth } diff --git a/server/docs/swagger_output.json b/server/docs/swagger_output.json index a823ac7..5266c5d 100644 --- a/server/docs/swagger_output.json +++ b/server/docs/swagger_output.json @@ -5,7 +5,7 @@ "title": "Jukebox API", "description": "Documentation automatically generated by the swagger-autogen module." }, - "host": "localhost:8000", + "host": "localhost:8080", "basePath": "/", "tags": [ { diff --git a/server/models/spotifyAuthModel.ts b/server/models/spotifyAuthModel.ts index aa6f603..3ab69fa 100644 --- a/server/models/spotifyAuthModel.ts +++ b/server/models/spotifyAuthModel.ts @@ -15,7 +15,9 @@ export interface ISpotifyAuthFields extends Omit userId: typeof Types.ObjectId } -export interface ISpotifyAuthMethods extends IModelMethods {} +export interface ISpotifyAuthMethods extends IModelMethods { + isExpired: () => boolean +} export type ISpotifyAuthModel = Model @@ -51,6 +53,12 @@ export const SpotifyAuthSchema = new Schema< } }) +SpotifyAuthSchema.methods.isExpired = function () { + const expiresAt: Date = this.expiresAt + + return expiresAt.getTime() <= Date.now() +} + SpotifyAuthSchema.methods.serialize = function () { return { id: this.id, diff --git a/server/services/spotifyService.ts b/server/services/spotifyService.ts index 52a8924..8912f62 100644 --- a/server/services/spotifyService.ts +++ b/server/services/spotifyService.ts @@ -1,4 +1,3 @@ -import type { Device } from '@spotify/web-api-ts-sdk' import { authenticateSpotify, getSpotifyEmail, @@ -76,6 +75,11 @@ export class SpotifyService { return await this.sdk.currentUser.profile() } + public async getAccessToken() { + const tokens = await this.sdk.getAccessToken() + return tokens?.access_token ?? '' + } + // public async getActiveDevice(failSilently: true): Promise // public async getActiveDevice(failSilently?: false): Promise // public async getActiveDevice(failSilently = false) { diff --git a/server/views/userViews.ts b/server/views/userViews.ts index b02e9fd..a03ec0e 100644 --- a/server/views/userViews.ts +++ b/server/views/userViews.ts @@ -5,7 +5,7 @@ import { requestPasswordReset, resetPassword } from 'server/controllers' -import { cleanUser, User, type IUser } from 'server/models' +import { cleanUser, Group, User, type IUser } from 'server/models' import { apiAuthRequest, apiRequest, httpCreated, Viewset, type ApiArgs } from 'server/utils' export const registerUserView = apiRequest( @@ -43,8 +43,11 @@ export const currentUserView = apiAuthRequest(async (req, res, next) => { */ const { user } = res.locals const userSerialized: IUser = user.serialize() + const userGroups = await Group.find({ ownerId: user._id }) + + const groups = userGroups.map((group) => ({ id: group._id, name: group.name })) - return userSerialized + return { ...userSerialized, groups } }) export const requestPasswordResetView = apiRequest(async (req, res, next) => {