Skip to content

Commit

Permalink
Add feature flag for gmail scopes
Browse files Browse the repository at this point in the history
  • Loading branch information
martmull committed Oct 8, 2024
1 parent 0c1d0c8 commit f053d52
Show file tree
Hide file tree
Showing 12 changed files with 87 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,5 @@ export type FeatureFlagKey =
| 'IS_WORKSPACE_FAVORITE_ENABLED'
| 'IS_SEARCH_ENABLED'
| 'IS_QUERY_RUNNER_TWENTY_ORM_ENABLED'
| 'IS_GMAIL_SEND_EMAIL_SCOPE_ENABLED'
| 'IS_WORKSPACE_MIGRATED_FOR_SEARCH';
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,11 @@ export const seedFeatureFlags = async (
workspaceId: workspaceId,
value: true,
},
{
key: FeatureFlagKey.IsGmailSendEmailScopeEnabled,
workspaceId: workspaceId,
value: true,
},
])
.execute();
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import { DataSourceModule } from 'src/engine/metadata-modules/data-source/data-s
import { WorkspaceDataSourceModule } from 'src/engine/workspace-datasource/workspace-datasource.module';
import { WorkspaceManagerModule } from 'src/engine/workspace-manager/workspace-manager.module';
import { ConnectedAccountModule } from 'src/modules/connected-account/connected-account.module';
import { FeatureFlagModule } from 'src/engine/core-modules/feature-flag/feature-flag.module';

import { AuthResolver } from './auth.resolver';

Expand All @@ -52,6 +53,7 @@ import { JwtAuthStrategy } from './strategies/jwt.auth.strategy';
OnboardingModule,
WorkspaceDataSourceModule,
ConnectedAccountModule,
FeatureFlagModule,
],
controllers: [
GoogleAuthController,
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,33 @@ import {
import { GoogleAPIsOauthExchangeCodeForTokenStrategy } from 'src/engine/core-modules/auth/strategies/google-apis-oauth-exchange-code-for-token.auth.strategy';
import { setRequestExtraParams } from 'src/engine/core-modules/auth/utils/google-apis-set-request-extra-params.util';
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
import { FeatureFlagService } from 'src/engine/core-modules/feature-flag/services/feature-flag.service';
import { FeatureFlagKey } from 'src/engine/core-modules/feature-flag/enums/feature-flag-key.enum';
import { TokenService } from 'src/engine/core-modules/auth/token/services/token.service';

@Injectable()
export class GoogleAPIsOauthExchangeCodeForTokenGuard extends AuthGuard(
'google-apis',
) {
constructor(private readonly environmentService: EnvironmentService) {
constructor(
private readonly environmentService: EnvironmentService,
private readonly featureFlagService: FeatureFlagService,
private readonly tokenService: TokenService,
) {
super();
}

async canActivate(context: ExecutionContext) {
const request = context.switchToHttp().getRequest();
const state = JSON.parse(request.query.state);
const { workspaceId } = await this.tokenService.verifyTransientToken(
state.transientToken,
);
const isGmailSendEmailScopeEnabled =
await this.featureFlagService.isFeatureEnabled(
FeatureFlagKey.IsGmailSendEmailScopeEnabled,
workspaceId,
);

if (
!this.environmentService.get('MESSAGING_PROVIDER_GMAIL_ENABLED') &&
Expand All @@ -34,6 +49,7 @@ export class GoogleAPIsOauthExchangeCodeForTokenGuard extends AuthGuard(
new GoogleAPIsOauthExchangeCodeForTokenStrategy(
this.environmentService,
{},
isGmailSendEmailScopeEnabled,
);

setRequestExtraParams(request, {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,17 @@ import {
import { GoogleAPIsOauthRequestCodeStrategy } from 'src/engine/core-modules/auth/strategies/google-apis-oauth-request-code.auth.strategy';
import { setRequestExtraParams } from 'src/engine/core-modules/auth/utils/google-apis-set-request-extra-params.util';
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
import { FeatureFlagService } from 'src/engine/core-modules/feature-flag/services/feature-flag.service';
import { FeatureFlagKey } from 'src/engine/core-modules/feature-flag/enums/feature-flag-key.enum';
import { TokenService } from 'src/engine/core-modules/auth/token/services/token.service';

@Injectable()
export class GoogleAPIsOauthRequestCodeGuard extends AuthGuard('google-apis') {
constructor(private readonly environmentService: EnvironmentService) {
constructor(
private readonly environmentService: EnvironmentService,
private readonly featureFlagService: FeatureFlagService,
private readonly tokenService: TokenService,
) {
super({
prompt: 'select_account',
});
Expand All @@ -20,6 +27,15 @@ export class GoogleAPIsOauthRequestCodeGuard extends AuthGuard('google-apis') {
async canActivate(context: ExecutionContext) {
const request = context.switchToHttp().getRequest();

const { workspaceId } = await this.tokenService.verifyTransientToken(
request.query.transientToken,
);
const isGmailSendEmailScopeEnabled =
await this.featureFlagService.isFeatureEnabled(
FeatureFlagKey.IsGmailSendEmailScopeEnabled,
workspaceId,
);

if (
!this.environmentService.get('MESSAGING_PROVIDER_GMAIL_ENABLED') &&
!this.environmentService.get('CALENDAR_PROVIDER_GOOGLE_ENABLED')
Expand All @@ -30,7 +46,11 @@ export class GoogleAPIsOauthRequestCodeGuard extends AuthGuard('google-apis') {
);
}

new GoogleAPIsOauthRequestCodeStrategy(this.environmentService, {});
new GoogleAPIsOauthRequestCodeStrategy(
this.environmentService,
{},
isGmailSendEmailScopeEnabled,
);
setRequestExtraParams(request, {
transientToken: request.query.transientToken,
redirectLocation: request.query.redirectLocation,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,9 @@ import {
MessagingMessageListFetchJobData,
} from 'src/modules/messaging/message-import-manager/jobs/messaging-message-list-fetch.job';
import { WorkspaceMemberWorkspaceEntity } from 'src/modules/workspace-member/standard-objects/workspace-member.workspace-entity';
import { GOOGLE_APIS_OAUTH_SCOPES } from 'src/engine/core-modules/auth/constants/google-apis-oauth-scopes';
import { getGoogleApisOauthScopes } from 'src/engine/core-modules/auth/utils/get-google-apis-oauth-scopes';
import { FeatureFlagService } from 'src/engine/core-modules/feature-flag/services/feature-flag.service';
import { FeatureFlagKey } from 'src/engine/core-modules/feature-flag/enums/feature-flag-key.enum';

@Injectable()
export class GoogleAPIsService {
Expand All @@ -45,6 +47,7 @@ export class GoogleAPIsService {
private readonly calendarQueueService: MessageQueueService,
private readonly environmentService: EnvironmentService,
private readonly accountsToReconnectService: AccountsToReconnectService,
private readonly featureFlagService: FeatureFlagService,
) {}

async refreshGoogleRefreshToken(input: {
Expand Down Expand Up @@ -96,6 +99,13 @@ export class GoogleAPIsService {
const workspaceDataSource =
await this.twentyORMGlobalManager.getDataSourceForWorkspace(workspaceId);

const isGmailSendEmailScopeEnabled =
await this.featureFlagService.isFeatureEnabled(
FeatureFlagKey.IsGmailSendEmailScopeEnabled,
workspaceId,
);
const scopes = getGoogleApisOauthScopes(isGmailSendEmailScopeEnabled);

await workspaceDataSource.transaction(async (manager: EntityManager) => {
if (!existingAccountId) {
await connectedAccountRepository.save(
Expand All @@ -106,7 +116,7 @@ export class GoogleAPIsService {
accessToken: input.accessToken,
refreshToken: input.refreshToken,
accountOwnerId: workspaceMemberId,
scopes: GOOGLE_APIS_OAUTH_SCOPES,
scopes,
},
{},
manager,
Expand Down Expand Up @@ -148,7 +158,7 @@ export class GoogleAPIsService {
{
accessToken: input.accessToken,
refreshToken: input.refreshToken,
scopes: GOOGLE_APIS_OAUTH_SCOPES,
scopes,
},
manager,
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { PassportStrategy } from '@nestjs/passport';
import { Strategy } from 'passport-google-oauth20';

import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
import { GOOGLE_APIS_OAUTH_SCOPES } from 'src/engine/core-modules/auth/constants/google-apis-oauth-scopes';
import { getGoogleApisOauthScopes } from 'src/engine/core-modules/auth/utils/get-google-apis-oauth-scopes';

export type GoogleAPIScopeConfig = {
isCalendarEnabled?: boolean;
Expand All @@ -19,12 +19,15 @@ export class GoogleAPIsOauthCommonStrategy extends PassportStrategy(
constructor(
environmentService: EnvironmentService,
scopeConfig: GoogleAPIScopeConfig,
isGmailSendEmailScopeEnabled = false,
) {
const scopes = getGoogleApisOauthScopes(isGmailSendEmailScopeEnabled);

super({
clientID: environmentService.get('AUTH_GOOGLE_CLIENT_ID'),
clientSecret: environmentService.get('AUTH_GOOGLE_CLIENT_SECRET'),
callbackURL: environmentService.get('AUTH_GOOGLE_APIS_CALLBACK_URL'),
scope: GOOGLE_APIS_OAUTH_SCOPES,
scope: scopes,
passReqToCallback: true,
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,9 @@ export class GoogleAPIsOauthExchangeCodeForTokenStrategy extends GoogleAPIsOauth
constructor(
environmentService: EnvironmentService,
scopeConfig: GoogleAPIScopeConfig,
isGmailSendEmailScopeEnabled = false,
) {
super(environmentService, scopeConfig);
super(environmentService, scopeConfig, isGmailSendEmailScopeEnabled);
}

async validate(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@ export class GoogleAPIsOauthRequestCodeStrategy extends GoogleAPIsOauthCommonStr
constructor(
environmentService: EnvironmentService,
scopeConfig: GoogleAPIScopeConfig,
isGmailSendEmailScopeEnabled = false,
) {
super(environmentService, scopeConfig);
super(environmentService, scopeConfig, isGmailSendEmailScopeEnabled);
}

authenticate(req: any, options: any) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
export const getGoogleApisOauthScopes = (
isGmailSendEmailScopeEnabled = false,
) => {
const scopes = [
'email',
'profile',
'https://www.googleapis.com/auth/gmail.readonly',
'https://www.googleapis.com/auth/calendar.events',
'https://www.googleapis.com/auth/profile.emails.read',
];

if (isGmailSendEmailScopeEnabled) {
scopes.push('https://www.googleapis.com/auth/gmail.send');
}

return scopes;
};
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,5 @@ export enum FeatureFlagKey {
IsWorkspaceFavoriteEnabled = 'IS_WORKSPACE_FAVORITE_ENABLED',
IsSearchEnabled = 'IS_SEARCH_ENABLED',
IsWorkspaceMigratedForSearch = 'IS_WORKSPACE_MIGRATED_FOR_SEARCH',
IsGmailSendEmailScopeEnabled = 'IS_GMAIL_SEND_EMAIL_SCOPE_ENABLED',
}

0 comments on commit f053d52

Please sign in to comment.