import axios from 'axios' import { config } from '@things-factory/env' /** * Label Studio SSO Service * * Handles JWT token acquisition from Label Studio for SSO authentication. * The client application requests JWT tokens from Label Studio's token API, * then uses cookie-based authentication to automatically log users in. */ export class LabelStudioSSOService { /** * Get Label Studio SSO configuration */ private static getConfig() { const labelStudioConfig = config.get('labelStudio', { serverUrl: 'http://localhost:8080', apiToken: '' }) return { serverUrl: labelStudioConfig.serverUrl, apiToken: labelStudioConfig.apiToken } } /** * Request JWT token from Label Studio for SSO authentication * * @param email User email address * @returns JWT token and expiry time, or null if failed * * @example * ```typescript * const tokenData = await LabelStudioSSOService.getSSOToken('user@example.com') * if (tokenData) { * console.log('Token:', tokenData.token) * console.log('Expires in:', tokenData.expires_in, 'seconds') * } * ``` */ static async getSSOToken(email: string): Promise<{ token: string; expires_in: number } | null> { const { serverUrl, apiToken } = this.getConfig() if (!apiToken) { console.error('[LSS SSO] Label Studio API token not configured') return null } if (!email) { console.error('[LSS SSO] Email is required') return null } try { console.log(`[LSS SSO] Requesting JWT token for: ${email}`) const response = await axios.post( `${serverUrl}/api/sso/token`, { email }, { headers: { 'Authorization': `Token ${apiToken}`, 'Content-Type': 'application/json' }, timeout: 5000 } ) const { token, expires_in } = response.data console.log(`[LSS SSO] JWT token acquired for ${email} (expires in ${expires_in}s)`) return { token, expires_in } } catch (error: any) { if (error.response) { console.error(`[LSS SSO] Label Studio API error: ${error.response.status}`, error.response.data) } else if (error.request) { console.error('[LSS SSO] No response from Label Studio:', error.message) } else { console.error('[LSS SSO] Request error:', error.message) } return null } } /** * Verify SSO configuration is properly set up * * @returns True if configuration is valid */ static verifyConfig(): boolean { const { serverUrl, apiToken } = this.getConfig() if (!serverUrl) { console.error('[LSS SSO] Label Studio server URL not configured') return false } if (!apiToken) { console.error('[LSS SSO] Label Studio API token not configured') return false } return true } }