Skip to content

Commit

Permalink
Merge pull request #8814 from ever-co/fix/passport-strategy
Browse files Browse the repository at this point in the history
[Fix] Passport Strategy Warning
  • Loading branch information
rahul-rocket authored Mar 1, 2025
2 parents ea2e050 + bad50be commit 0f2b63f
Show file tree
Hide file tree
Showing 42 changed files with 538 additions and 347 deletions.
2 changes: 1 addition & 1 deletion .env.compose
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ AUTH0_DOMAIN=XXXXXXX

KEYCLOAK_REALM=XXXXXXX
KEYCLOAK_CLIENT_ID=XXXXXXX
KEYCLOAK_SECRET=XXXXXXX
KEYCLOAK_CLIENT_SECRET=XXXXXXX
KEYCLOAK_AUTH_SERVER_URL=XXXXXXX
KEYCLOAK_COOKIE_KEY=XXXXXXX

Expand Down
2 changes: 1 addition & 1 deletion .env.demo.compose
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ AUTH0_DOMAIN=XXXXXXX

KEYCLOAK_REALM=XXXXXXX
KEYCLOAK_CLIENT_ID=XXXXXXX
KEYCLOAK_SECRET=XXXXXXX
KEYCLOAK_CLIENT_SECRET=XXXXXXX
KEYCLOAK_AUTH_SERVER_URL=XXXXXXX
KEYCLOAK_COOKIE_KEY=XXXXXXX

Expand Down
2 changes: 1 addition & 1 deletion .env.sample
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ AUTH0_DOMAIN=XXXXXXX

KEYCLOAK_REALM=XXXXXXX
KEYCLOAK_CLIENT_ID=XXXXXXX
KEYCLOAK_SECRET=XXXXXXX
KEYCLOAK_CLIENT_SECRET=XXXXXXX
KEYCLOAK_AUTH_SERVER_URL=XXXXXXX
KEYCLOAK_COOKIE_KEY=XXXXXXX

Expand Down
6 changes: 3 additions & 3 deletions packages/auth/src/lib/auth0/auth0.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,13 @@ export class Auth0Controller {
/**
* Handles the callback from Auth0 after a successful login.
*
* @param requestCtx - The context of the incoming request, including the authenticated user information.
* @param context - The context of the incoming request, including the authenticated user information.
* @param res - The response object used to send a redirect or response to the client.
* @returns {Promise<void>} - A promise that resolves after redirecting the user.
*/
@Get('/auth0/callback')
async auth0LoginCallback(@RequestCtx() requestCtx: IIncomingRequest, @Res() res: Response) {
const { user } = requestCtx;
async auth0LoginCallback(@RequestCtx() context: IIncomingRequest, @Res() res: Response): Promise<any> {
const { user } = context;
const { success, authData } = await this.service.validateOAuthLoginEmail(user.emails);
return this.service.routeRedirect(success, authData, res);
}
Expand Down
35 changes: 22 additions & 13 deletions packages/auth/src/lib/auth0/auth0.strategy.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,38 @@
import { Injectable } from '@nestjs/common';
import { PassportStrategy } from '@nestjs/passport';
import { Strategy } from 'passport-auth0';
import { ConfigService, IEnvironment } from '@gauzy/config';
import { ConfigService } from '@gauzy/config';

@Injectable()
export class Auth0Strategy extends PassportStrategy(Strategy, 'auth0') {
constructor(readonly configService: ConfigService) {
super(config(configService));
super(parseAuth0Config(configService));
}
}

/**
* Generates the configuration object for Auth0 authentication.
*
* @param configService - The `ConfigService` instance used to access environment-specific configurations.
* @returns {object} - The configuration object for Auth0, including client ID, client secret, domain, and callback URL.
* @param {ConfigService} configService - The configuration service instance.
* @returns {Record<string, string>} - The Auth0 configuration object.
* @throws {Error} If required Auth0 configuration values are missing.
*/
export const config = (configService: ConfigService) => {
const AUTH0_CONFIG = configService.get('auth0Config') as IEnvironment['auth0Config'];
const { baseUrl } = configService.apiConfigOptions;
export const parseAuth0Config = (configService: ConfigService): Record<string, string> => {
// Retrieve Auth0 configuration from the environment
const auth0Config = configService.get('auth0Config');
// Retrieve API base URL
const { baseUrl } = configService.getConfigValue('apiConfigOptions');

return {
clientID: AUTH0_CONFIG.clientID || 'disabled', // Auth0 Client ID or default value
clientSecret: AUTH0_CONFIG.clientSecret || 'disabled', // Auth0 Client Secret or default value
domain: AUTH0_CONFIG.domain || 'disabled', // Auth0 Domain or default value
callbackURL: `${baseUrl}/auth/auth0/callback` // Constructed callback URL
};
// Validate required configurations
if (!auth0Config.clientID || !auth0Config.clientSecret || !auth0Config.domain) {
console.warn('⚠️ Auth0 configuration is missing some required values. Defaulting to "disabled".');
}

// Construct and return the Auth0 configuration object
return {
clientID: auth0Config.clientID ?? 'disabled',
clientSecret: auth0Config.clientSecret ?? 'disabled',
domain: auth0Config.domain ?? 'disabled',
callbackURL: `${baseUrl ?? 'http://localhost:3000'}/api/auth/auth0/callback` // Ensure a fallback URL
};
};
6 changes: 3 additions & 3 deletions packages/auth/src/lib/facebook/facebook.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,13 @@ export class FacebookController {
/**
* Facebook login callback endpoint.
*
* @param requestCtx - The context of the incoming request.
* @param context - The context of the incoming request.
* @param res - The response object.
* @returns The result of the Facebook login callback.
*/
@Get('/facebook/callback')
async facebookLoginCallback(@RequestCtx() requestCtx: IIncomingRequest, @Res() res: Response) {
const { user } = requestCtx;
async facebookLoginCallback(@RequestCtx() context: IIncomingRequest, @Res() res: Response): Promise<any> {
const { user } = context;
const { success, authData } = await this.service.validateOAuthLoginEmail(user.emails);
return this.service.routeRedirect(success, authData, res);
}
Expand Down
79 changes: 48 additions & 31 deletions packages/auth/src/lib/facebook/facebook.strategy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,55 +5,72 @@ import { Profile, Strategy } from 'passport-facebook';

@Injectable()
export class FacebookStrategy extends PassportStrategy(Strategy, 'facebook') {
constructor(protected readonly configService: ConfigService) {
super(config(configService));
constructor(readonly configService: ConfigService) {
super(parseFacebookConfig(configService));
}

/**
* Validates and extracts user information from Facebook OAuth profile.
*
* @param accessToken
* @param refreshToken
* @param profile
* @param done
* This method is called after successful authentication with Facebook.
* It processes the profile data and constructs a user object.
*
* @param {string} accessToken - The OAuth access token received from Facebook.
* @param {string} refreshToken - The refresh token (not used in Facebook OAuth).
* @param {Profile} profile - The Facebook user's profile data.
* @param {(err: any, user?: any, info?: any) => void} done - Callback function to indicate authentication success or failure.
*
* @returns {Promise<void>} - Resolves after processing the user profile.
*/
async validate(
accessToken: string,
refreshToken: string,
profile: Profile,
done: (err: any, user: any, info?: any) => void
): Promise<any> {
done: (err: any, user?: any, info?: any) => void
): Promise<void> {
try {
console.log('Facebook OAuth validate:', profile);
// Extract relevant information from the user's profile
const { emails } = profile;
const user = { emails, accessToken };

// Construct user object
const user = {
emails,
accessToken,
refreshToken
};

// Pass the user object to the callback to indicate successful authentication
done(null, user);
} catch (err) {
done(err, false);
} catch (error) {
console.error('Error during Facebook OAuth validation:', error);
done(error, false);
}
}
}

/**
* Creates a configuration object for Facebook OAuth based on the provided ConfigService.
* Generates the configuration object for Facebook OAuth authentication.
*
* @param configService - An instance of the ConfigService to retrieve configuration values.
* @returns An object containing Facebook OAuth configuration.
* @param {ConfigService} configService - The configuration service instance.
* @returns {Record<string, any>} - The Facebook OAuth configuration object.
* @throws {Error} If required Facebook OAuth configuration values are missing.
*/
export const config = (configService: ConfigService) => ({
// Retrieve Facebook OAuth client ID from the configuration service, default to 'disabled' if not found.
clientID: <string>configService.get<string>('facebook.clientId') || 'disabled',
export const parseFacebookConfig = (configService: ConfigService): Record<string, any> => {
const clientID = configService.get<string>('facebook.clientId');
const clientSecret = configService.get<string>('facebook.clientSecret');
const callbackURL = configService.get<string>('facebook.callbackURL');

// Retrieve Facebook OAuth client secret from the configuration service, default to 'disabled' if not found.
clientSecret: <string>configService.get<string>('facebook.clientSecret') || 'disabled',

// Retrieve Facebook OAuth callback URL from the configuration service.
callbackURL: <string>configService.get<string>('facebook.callbackURL'),

// Specify the scope for Facebook OAuth (in this case, only 'email').
scope: 'email',

// Specify the profile fields to request from Facebook (id, emails, name).
profileFields: ['id', 'emails', 'name'],
if (!clientID || !clientSecret || !callbackURL) {
console.warn('⚠️ Facebook OAuth configuration is incomplete. Defaulting to "disabled".');
}

// Enable proof of authentication.
enableProof: true
});
return {
clientID: clientID || 'disabled',
clientSecret: clientSecret || 'disabled',
callbackURL: callbackURL || `${process.env.API_BASE_URL ?? 'http://localhost:3000'}/api/auth/facebook/callback`,
scope: ['email'],
profileFields: ['id', 'emails', 'name'],
enableProof: true
};
};
59 changes: 38 additions & 21 deletions packages/auth/src/lib/fiverr/fiverr.strategy.ts
Original file line number Diff line number Diff line change
@@ -1,46 +1,63 @@
import { Injectable } from '@nestjs/common';
import { PassportStrategy } from '@nestjs/passport';
import { Strategy } from 'passport-google-oauth20';
import { ConfigService, IEnvironment } from '@gauzy/config';
import { ConfigService } from '@gauzy/config';
import passport from 'passport';

@Injectable()
export class FiverrStrategy extends PassportStrategy(Strategy, 'fiverr') {
constructor(readonly configService: ConfigService) {
super(config(configService));
super(parseFiverrConfig(configService));
}

async validate(profile, done: Function) {
passport['_strategies'].session.role_name = '';
/**
* Validates and extracts user information from Fiverr's OAuth profile.
*
* @param {any} profile - The user profile returned by Fiverr.
* @param {Function} done - The callback function to complete authentication.
*/
async validate(profile: any, done: (error: any, user?: any) => void) {
try {
try {
const { emails } = profile;
const user = {
emails
};
done(null, user);
} catch (err) {
done(err, false);
console.log('Fiverr OAuth validate:', profile);

// Ensure session strategy exists before modifying
if (passport['_strategies'].session) {
passport['_strategies'].session.role_name = '';
}
} catch (err) {
done(err, false);

const { emails } = profile || {};
const user = { emails };

done(null, user);
} catch (error) {
console.error('Fiverr OAuth validation error:', error);
done(error, false);
}
}
}

/**
* Retrieves the configuration for the Fiverr OAuth strategy.
*
* @param configService
* @returns
* @param {ConfigService} configService - The configuration service instance.
* @returns {Record<string, string | boolean>} - The configuration object for Fiverr authentication.
* @throws {Error} If required Fiverr configuration values are missing.
*/
export const config = (configService: ConfigService) => {
const FIVERR_CONFIG = configService.get('fiverrConfig') as IEnvironment['fiverrConfig'];
export const parseFiverrConfig = (configService: ConfigService): Record<string, string | boolean> => {
// Retrieve Fiverr configuration from the environment
const fiverrConfig = configService.get('fiverrConfig');
// Retrieve API base URL
const { baseUrl } = configService.apiConfigOptions;

// Validate required Fiverr configurations
if (!fiverrConfig?.clientId || !fiverrConfig?.clientSecret) {
console.warn('⚠️ Fiverr authentication configuration is incomplete. Defaulting to "disabled".');
}

return {
clientID: FIVERR_CONFIG.clientId || 'disabled',
clientSecret: FIVERR_CONFIG.clientSecret || 'disabled',
callbackURL: `${baseUrl}/api/auth/fiverr/callback`,
clientID: fiverrConfig?.clientId ?? 'disabled',
clientSecret: fiverrConfig?.clientSecret ?? 'disabled',
callbackURL: `${baseUrl ?? 'http://localhost:3000'}/api/auth/fiverr/callback`, // Ensure a fallback URL
passReqToCallback: true
};
};
4 changes: 2 additions & 2 deletions packages/auth/src/lib/github/github.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ export class GithubController {
* @returns The result of the GitHub login callback.
*/
@Get('/github/callback')
async githubLoginCallback(@RequestCtx() _req: IIncomingRequest, @Res() _res: Response) {
const { user } = _req;
async githubLoginCallback(@RequestCtx() context: IIncomingRequest, @Res() _res: Response): Promise<any> {
const { user } = context;

// To-DO: Determine the frontend URL based on the request

Expand Down
Loading

0 comments on commit 0f2b63f

Please sign in to comment.