UNPKG

repoweaver

Version:

A GitHub App that skillfully weaves multiple templates together to create and update repositories with intelligent merge strategies

168 lines 6.24 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.SessionManager = exports.AuthManager = void 0; const rest_1 = require("@octokit/rest"); class AuthManager { constructor(clientId, clientSecret, database) { this.clientId = clientId; this.clientSecret = clientSecret; this.database = database; } getAuthorizationUrl(state) { const params = new URLSearchParams({ client_id: this.clientId, redirect_uri: `${process.env.APP_URL}/auth/callback`, scope: 'user:email', state: state || '', }); return `https://github.com/login/oauth/authorize?${params}`; } async handleCallback(code, state) { try { // Exchange code for access token const tokenResponse = await fetch('https://github.com/login/oauth/access_token', { method: 'POST', headers: { Accept: 'application/json', 'Content-Type': 'application/json', }, body: JSON.stringify({ client_id: this.clientId, client_secret: this.clientSecret, code, redirect_uri: `${process.env.APP_URL}/auth/callback`, }), }); const tokenData = (await tokenResponse.json()); if (tokenData.error) { throw new Error(`OAuth error: ${tokenData.error_description}`); } // Get user information const octokit = new rest_1.Octokit({ auth: tokenData.access_token, }); const userResponse = await octokit.rest.users.getAuthenticated(); const user = userResponse.data; // Check if user has any installations const installationsResponse = await octokit.rest.apps.listInstallationsForAuthenticatedUser({ per_page: 100, }); const installations = installationsResponse.data.installations; let installationId; if (installations.length > 0) { // For simplicity, use the first installation // In a real app, you might want to let the user choose installationId = installations[0].id; } const authenticatedUser = { id: user.id, login: user.login, name: user.name || user.login, email: user.email || '', avatarUrl: user.avatar_url, installationId, }; // Store user session await this.database.createUserSession({ userId: user.id, login: user.login, accessToken: tokenData.access_token, installationId, createdAt: new Date(), }); return authenticatedUser; } catch (error) { throw new Error(`Authentication failed: ${error}`); } } async authenticateMiddleware(req, res, next) { try { const authHeader = req.headers.authorization; if (!authHeader || !authHeader.startsWith('Bearer ')) { res.status(401).json({ error: 'No valid authorization header' }); return; } const token = authHeader.substring(7); const session = await this.database.getUserSessionByToken(token); if (!session) { res.status(401).json({ error: 'Invalid token' }); return; } // Verify token is still valid with GitHub const octokit = new rest_1.Octokit({ auth: session.accessToken, }); const userResponse = await octokit.rest.users.getAuthenticated(); const user = userResponse.data; req.user = { id: user.id, login: user.login, name: user.name || user.login, email: user.email || '', avatarUrl: user.avatar_url, installationId: session.installationId, }; next(); } catch (error) { res.status(401).json({ error: 'Authentication failed' }); } } async requireInstallation(req, res, next) { if (!req.user?.installationId) { res.status(403).json({ error: 'GitHub App installation required', message: 'Please install the RepoWeaver app to your GitHub account or organization', }); return; } next(); } async logout(userId) { await this.database.deleteUserSession(userId); } async getInstallationRepositories(installationId) { try { const octokit = new rest_1.Octokit({ auth: `Bearer ${process.env.GITHUB_ACCESS_TOKEN}`, }); const response = await octokit.rest.apps.listReposAccessibleToInstallation({ installation_id: installationId, per_page: 100, }); return response.data.repositories; } catch (error) { console.error('Failed to get installation repositories:', error); return []; } } } exports.AuthManager = AuthManager; class SessionManager { constructor() { this.sessions = new Map(); } generateSessionToken() { return Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15); } createSession(user) { const token = this.generateSessionToken(); this.sessions.set(token, user); return token; } getSession(token) { return this.sessions.get(token); } deleteSession(token) { this.sessions.delete(token); } cleanup() { // In a real implementation, you'd clean up expired sessions // For now, we'll just log the session count console.log(`Active sessions: ${this.sessions.size}`); } } exports.SessionManager = SessionManager; //# sourceMappingURL=auth.js.map