HEX
Server: LiteSpeed
System: Linux houston.panomity.com 6.8.0-100-generic #100-Ubuntu SMP PREEMPT_DYNAMIC Tue Jan 13 16:40:06 UTC 2026 x86_64
User: nudepix (1011)
PHP: 7.4.33
Disabled: pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare,
Upload Files
File: //opt/agentcloud/webapp/src/controllers/oauth.ts
'use strict';

import getAirbyteApi, { AirbyteApiType } from 'airbyte/api';
import debug from 'debug';
import createAccount from 'lib/account/create';
import { ObjectId } from 'mongodb';
import { OAUTH_PROVIDER, OAuthStrategy } from 'struct/oauth';

import { Account, addAccount, getAccountByOAuthOrEmail, setAccountOauth } from '../db/account';
import { addOrg } from '../db/org';
import { addTeam } from '../db/team';
const log = debug('webapp:oauth');

//To reduce some boilerplace in the router, allows us to just loop and create handlers for each service
import { Strategy as GitHubStrategy } from 'passport-github';
import { Strategy as GoogleStrategy } from 'passport-google-oauth20';
import { Strategy as HubspotStrategy } from 'passport-hubspot-oauth2';
import { Strategy as StripeStrategy } from 'passport-stripe';
export const OAUTH_STRATEGIES: OAuthStrategy[] = [
	{ strategy: GitHubStrategy, env: 'GITHUB', callback: githubCallback, path: '/auth/github/callback', extra: { scope: ['user:email'] } },
	{ strategy: GoogleStrategy, env: 'GOOGLE', callback: googleCallback, path: '/auth/google/callback', extra: { /* N/A */ } },
	{ strategy: StripeStrategy, env: 'STRIPE', callback: stripeCallback, path: '/auth/stripe/callback', extra: { /* N/A */ } },
	{ strategy: HubspotStrategy, env: 'HUBSPOT', callback: hubspotCallback, path: '/auth/hubspot/callback', extra: { /* N/A */ } },
];

export async function githubCallback(accessToken, refreshToken, profile, done) {
	log(`githubCallback profile: ${JSON.stringify(profile, null, '\t')}`);
	const emails = await fetch('https://api.github.com/user/emails', {
		headers: {
			'User-Agent': 'Agentcloud',
			'Authorization': `token ${accessToken}`,
		}
	}).then(res => res.json());
	const primaryEmail = emails.find(email => (email.primary && email.verified)).email;
	profile.provider = OAUTH_PROVIDER.GITHUB;
	profile.email = primaryEmail;
	const account: Account = await getAccountByOAuthOrEmail(profile.id, profile.provider, profile.email);
	log('githubCallback account', account);
	await createUpdateAccountOauth(account, profile.displayName, profile.email, profile.provider, profile.id);	
	done(null, profile);
}

export async function googleCallback(accessToken, refreshToken, profile, done) {
	log(`googleCallback profile: ${JSON.stringify(profile, null, '\t')}`);
	const verifiedEmail = profile.emails.find(e => e.verified === true).value;
	profile.provider = OAUTH_PROVIDER.GOOGLE;
	profile.email = verifiedEmail;
	const account: Account = await getAccountByOAuthOrEmail(profile.id, profile.provider, profile.email);
	log('googleCallback account', account);
	await createUpdateAccountOauth(account, profile.displayName, verifiedEmail, profile.provider, profile.id);
	done(null, profile);
}

export async function stripeCallback(accessToken, refreshToken, profile, done) {
	log(`stripeCallback profile: ${JSON.stringify(profile, null, '\t')}`);
	done(null, profile);
}

export async function hubspotCallback(accessToken, refreshToken, profile, done) {
	log(`hubspotCallback profile: ${JSON.stringify(profile, null, '\t')}`);
	done(null, profile);
}

export async function serializeHandler(user, done) {
	log('serializeHandler user', user);
	done(null, { oauthId: user.id, provider: user.provider });
}

export async function deserializeHandler(obj, done) {
	log('deserializeHandler obj', obj);
	const { oauthId, provider } = obj;
    // Use provider information to retrieve the user e.g.
	const account: Account = await getAccountByOAuthOrEmail(oauthId, provider, null);
	if (account) {
		const accountObj = {
			_id: account._id.toString(),
			name: account.name,
			email: account.email,
			orgs: account.orgs,
			currentOrg: account.currentOrg,
			currentTeam: account.currentTeam,
			token: account.token,
			stripe: account.stripe,
			oauth: account.oauth,
		};
		return done(null, accountObj);
	}
	done(null, null);
}

async function createUpdateAccountOauth(account, email, name, provider, profileId) {
	if (!account) {
		await createAccount(email, name || email, null, false, provider as OAUTH_PROVIDER, profileId);
	} else {
		//existing account, check if it has the oauth ID else update it
		if (!account.oauth || !account.oauth[provider]) {
			await setAccountOauth(account._id, profileId, provider);
		}
	}
}