Highly ambitious ATProtocol AppView service and sdks
at main 66 lines 2.1 kB view raw
1import type { AuthProvider } from "@slices/client"; 2import { AtProtoClient } from "../generated_client.ts"; 3import { ConfigManager } from "../auth/config.ts"; 4import { checkUserWaitlistAccess, showWaitlistError } from "./waitlist.ts"; 5 6class DeviceAuthProvider implements AuthProvider { 7 private config: ConfigManager; 8 9 constructor(config: ConfigManager) { 10 this.config = config; 11 } 12 13 async ensureValidToken(): Promise<{ accessToken: string; tokenType?: string }> { 14 await this.config.load(); 15 16 if (!this.config.isAuthenticated()) { 17 throw new Error("Not authenticated. Run 'slices login' first."); 18 } 19 20 const authConfig = this.config.get().auth!; 21 22 // Check if token is expired 23 if (authConfig.expiresAt && authConfig.expiresAt <= Date.now()) { 24 throw new Error("Access token has expired. Please re-authenticate using 'slices login'."); 25 } 26 27 return { 28 accessToken: authConfig.accessToken, 29 tokenType: "Bearer", 30 }; 31 } 32 33 async refreshAccessToken(): Promise<{ accessToken: string; tokenType?: string }> { 34 return await this.ensureValidToken(); 35 } 36} 37 38export async function createAuthenticatedClient(sliceUri: string, apiUrl = "https://api.slices.network"): Promise<AtProtoClient> { 39 const config = new ConfigManager(); 40 await config.load(); 41 42 if (!config.isAuthenticated()) { 43 throw new Error("Not authenticated. Run 'slices login' first."); 44 } 45 46 const authConfig = config.get().auth!; 47 48 if (!authConfig.did) { 49 throw new Error("Missing user DID in authentication config. Please re-authenticate using 'slices login'."); 50 } 51 52 // Only check waitlist access for production Slices network 53 if (apiUrl === "https://api.slices.network") { 54 const { hasAccess, isOnWaitlist } = await checkUserWaitlistAccess(authConfig.did, apiUrl); 55 56 if (!hasAccess) { 57 showWaitlistError(authConfig.did, isOnWaitlist); 58 Deno.exit(1); 59 } 60 } 61 62 // Create simple auth provider that uses stored device flow tokens 63 const authProvider = new DeviceAuthProvider(config); 64 65 return new AtProtoClient(apiUrl, sliceUri, authProvider); 66}