mirror of
				https://github.com/Dan6erbond/sk-auth.git
				synced 2025-10-26 10:22:56 +01:00 
			
		
		
		
	* ✨ Inject auth instance into provider `signin()` and `callback()` methods Add generic OAuth provider to implement with simple config. * 🐛 Fix storing multiple social connections in demo app * ✨ Create `apiKey` and `apiSecret` aliases for Reddit provider * ⬆️ Reinstall local dep * 🏷️ Remove comments / use `OAuth2ProviderConfig` for `GoogleOAuth2Provider` types
		
			
				
	
	
		
			88 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			88 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
| import type { ServerRequest } from "@sveltejs/kit/types/endpoint";
 | |
| import type { CallbackResult } from "../types";
 | |
| import { OAuth2BaseProvider, OAuth2BaseProviderConfig } from "./oauth2.base";
 | |
| 
 | |
| interface TwitterAuthProviderConfig extends OAuth2BaseProviderConfig {
 | |
|   apiKey: string;
 | |
|   apiSecret: string;
 | |
| }
 | |
| 
 | |
| const defaultConfig: Partial<TwitterAuthProviderConfig> = {
 | |
|   id: "twitter",
 | |
| };
 | |
| 
 | |
| export class TwitterAuthProvider extends OAuth2BaseProvider<TwitterAuthProviderConfig> {
 | |
|   constructor(config: TwitterAuthProviderConfig) {
 | |
|     super({
 | |
|       ...defaultConfig,
 | |
|       ...config,
 | |
|     });
 | |
|   }
 | |
| 
 | |
|   async getRequestToken(host: string) {
 | |
|     const endpoint = "https://api.twitter.com/oauth/request_token";
 | |
| 
 | |
|     const data = {
 | |
|       oauth_callback: encodeURIComponent(this.getCallbackUri(host)),
 | |
|       oauth_consumer_key: this.config.apiKey,
 | |
|     };
 | |
| 
 | |
|     const res = await fetch(`${endpoint}?${new URLSearchParams(data)}`, { method: "POST" });
 | |
|     const { oauth_token, oauth_token_secret, oauth_callback_confirmed } = await res.json();
 | |
| 
 | |
|     return {
 | |
|       oauthToken: oauth_token,
 | |
|       oauthTokenSecret: oauth_token_secret,
 | |
|       oauthCallbackConfirmed: oauth_callback_confirmed,
 | |
|     };
 | |
|   }
 | |
| 
 | |
|   async getAuthorizationUrl({ host }: ServerRequest) {
 | |
|     const endpoint = "https://api.twitter.com/oauth/authorize";
 | |
| 
 | |
|     const { oauthToken } = await this.getRequestToken(host);
 | |
| 
 | |
|     const data = {
 | |
|       oauth_token: oauthToken,
 | |
|     };
 | |
| 
 | |
|     const url = `${endpoint}?${new URLSearchParams(data)}`;
 | |
|     return url;
 | |
|   }
 | |
| 
 | |
|   async getTokens(oauthToken: string, oauthVerifier: string) {
 | |
|     const endpoint = "https://api.twitter.com/oauth/access_token";
 | |
| 
 | |
|     const data = {
 | |
|       oauth_consumer_key: this.config.apiKey,
 | |
|       oauth_token: oauthToken,
 | |
|       oauth_verifier: oauthVerifier,
 | |
|     };
 | |
| 
 | |
|     const res = await fetch(`${endpoint}?${new URLSearchParams(data)}`, { method: "POST" });
 | |
|     return await res.json();
 | |
|   }
 | |
| 
 | |
|   async getUserProfile({ oauth_token, oauth_token_secret: _ }: any) {
 | |
|     const endpoint = "https://api.twitter.com/1.1/account/verify_credentials.json";
 | |
| 
 | |
|     const res = await fetch(endpoint, { headers: { Authorization: `Bearer ${oauth_token}` } });
 | |
|     return await res.json();
 | |
|   }
 | |
| 
 | |
|   async callback({ query, host }: ServerRequest): Promise<CallbackResult> {
 | |
|     const oauthToken = query.get("oauth_token");
 | |
|     const oauthVerifier = query.get("oauth_verifier");
 | |
|     const redirect = this.getStateValue(query, "redirect");
 | |
| 
 | |
|     const tokens = await this.getTokens(oauthToken!, oauthVerifier!);
 | |
|     let user = await this.getUserProfile(tokens);
 | |
| 
 | |
|     if (this.config.profile) {
 | |
|       user = await this.config.profile(user, tokens);
 | |
|     }
 | |
| 
 | |
|     return [user, redirect ?? this.getUri(host, "/")];
 | |
|   }
 | |
| }
 |