diff --git a/app/src/global.d.ts b/app/src/global.d.ts index d648a04..a4a6c44 100644 --- a/app/src/global.d.ts +++ b/app/src/global.d.ts @@ -3,6 +3,8 @@ interface ImportMetaEnv { VITE_GOOGLE_OAUTH_CLIENT_ID: string; VITE_GOOGLE_OAUTH_CLIENT_SECRET: string; + VITE_TWITCH_OAUTH_CLIENT_ID: string; + VITE_TWITCH_OAUTH_CLIENT_SECRET: string; VITE_FACEBOOK_OAUTH_CLIENT_ID: string; VITE_FACEBOOK_OAUTH_CLIENT_SECRET: string; VITE_TWITTER_API_KEY: string; diff --git a/app/src/lib/appAuth.ts b/app/src/lib/appAuth.ts index 315fa63..f337b64 100644 --- a/app/src/lib/appAuth.ts +++ b/app/src/lib/appAuth.ts @@ -1,5 +1,6 @@ import { SvelteKitAuth } from "sk-auth"; import { + TwitchOAuth2Provider, FacebookOAuth2Provider, GoogleOAuth2Provider, RedditOAuth2Provider, @@ -15,6 +16,13 @@ export const appAuth = new SvelteKitAuth({ return { ...profile, provider: "google" }; }, }), + new TwitchOAuth2Provider({ + clientId: import.meta.env.VITE_TWITCH_OAUTH_CLIENT_ID, + clientSecret: import.meta.env.VITE_TWITCH_OAUTH_CLIENT_SECRET, + profile(profile) { + return { ...profile, provider: "twitch" }; + }, + }), new FacebookOAuth2Provider({ clientId: import.meta.env.VITE_FACEBOOK_OAUTH_CLIENT_ID, clientSecret: import.meta.env.VITE_FACEBOOK_OAUTH_CLIENT_SECRET, diff --git a/app/src/routes/login.svelte b/app/src/routes/login.svelte index b897ec2..df5cf77 100644 --- a/app/src/routes/login.svelte +++ b/app/src/routes/login.svelte @@ -36,6 +36,38 @@
+ + + + + Sign in with Twitch + + ; + +const defaultConfig: Partial = { + id: "twitch", + scope: "user:read:email", + accessTokenUrl: "https://id.twitch.tv/oauth2/token", + authorizationUrl: "https://id.twitch.tv/oauth2/authorize", + profileUrl: "https://api.twitch.tv/helix/users", +}; + +export class TwitchOAuth2Provider extends OAuth2Provider< + TwitchProfile, + TwitchTokens, + TwitchOAuth2ProviderConfig +> { + constructor(config: TwitchOAuth2ProviderConfig) { + super({ + ...defaultConfig, + ...config, + }); + } + + async getUserProfile(tokens: TwitchTokens): Promise { + const headers = { + 'Client-ID': this.config.clientId + '', + 'Accept': 'application/vnd.twitchtv.v5+json', + 'Authorization': `Bearer ${tokens.access_token}` + }; + const { data: [profile] } = await fetch(this.config.profileUrl!, { headers: headers }).then(res => res.json()) + return profile + } +}