Something went wrong. Try again.
A fork of @slices.network/slices forked from slices.network/slices
Something went wrong. Try again.
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980import { DeviceFlowClient, type OAuthUserInfo } from "@slices/oauth";import { logger } from "../utils/logger.ts";import { ConfigManager } from "./config.ts";import { checkUserWaitlistAccess, showWaitlistError } from "../utils/waitlist.ts";
const DEFAULT_AIP_BASE_URL = "https://auth.slices.network";const DEFAULT_CLIENT_ID = "24e77d48-a892-4043-b113-ea241f339397";const DEFAULT_SCOPE = "atproto transition:generic repo:network.slices.slice repo:network.slices.lexicon repo:network.slices.actor.profile repo:network.slices.waitlist.request";
export async function performDeviceFlow( aipBaseUrl: string = DEFAULT_AIP_BASE_URL, clientId: string = DEFAULT_CLIENT_ID, scope: string = DEFAULT_SCOPE,): Promise<void> { const deviceClient = new DeviceFlowClient(aipBaseUrl, clientId); const config = new ConfigManager(); await config.load();
try { const authResponse = await deviceClient.requestDeviceAuthorization(scope);
console.log(`\n${authResponse.verification_uri_complete}`); console.log(`Code: ${authResponse.user_code}\n`);
if (authResponse.verification_uri_complete) { try { const command = Deno.build.os === "darwin" ? "open" : Deno.build.os === "windows" ? "cmd" : "xdg-open"; const args: string[] = Deno.build.os === "windows" ? ["/c", "start", authResponse.verification_uri_complete] : [authResponse.verification_uri_complete]; await new Deno.Command(command, { args }).output(); } catch { console.log("Could not open browser automatically. Please open the link manually.\n"); } }
const tokenResponse = await deviceClient.pollForToken( authResponse.device_code, authResponse.interval || 5, authResponse.expires_in, );
const userInfo: OAuthUserInfo = await deviceClient.getUserInfo(tokenResponse.access_token);
if (!userInfo.did) { throw new Error("Failed to retrieve user DID from authentication response."); }
// Only check waitlist access for production Slices network if (aipBaseUrl === "https://auth.slices.network") { const { hasAccess, isOnWaitlist } = await checkUserWaitlistAccess(userInfo.did);
if (!hasAccess) { showWaitlistError(userInfo.did, isOnWaitlist); throw new Error("Access denied: User is not on the invite list"); } }
const expiresAt = tokenResponse.expires_in ? Date.now() + (tokenResponse.expires_in * 1000) : undefined;
await config.save({ auth: { accessToken: tokenResponse.access_token, refreshToken: tokenResponse.refresh_token, expiresAt, did: userInfo.did, aipBaseUrl, }, });
console.log(`✓ Logged in as ${userInfo.did}`);
} catch (error) { const err = error as Error; logger.error("Authentication failed:", err.message); throw error; }}