5748 Create contacts for emails sent and received by email aliases (#5855)
Closes #5748 - Create feature flag - Add scope `https://www.googleapis.com/auth/profile.emails.read` when connecting an account - Get email aliases with google people API, store them in connectedAccount and refresh them before each message-import - Update the contact creation logic accordingly - Refactor --------- Co-authored-by: Charles Bochet <charles@twenty.com>
This commit is contained in:
@ -9,14 +9,14 @@ import {
|
||||
|
||||
import { Response } from 'express';
|
||||
|
||||
import { GoogleAPIsProviderEnabledGuard } from 'src/engine/core-modules/auth/guards/google-apis-provider-enabled.guard';
|
||||
import { GoogleAPIsOauthGuard } from 'src/engine/core-modules/auth/guards/google-apis-oauth.guard';
|
||||
import { GoogleAPIsRequest } from 'src/engine/core-modules/auth/strategies/google-apis.auth.strategy';
|
||||
import { GoogleAPIsOauthRequestCodeGuard } from 'src/engine/core-modules/auth/guards/google-apis-oauth-request-code.guard';
|
||||
import { GoogleAPIsService } from 'src/engine/core-modules/auth/services/google-apis.service';
|
||||
import { TokenService } from 'src/engine/core-modules/auth/services/token.service';
|
||||
import { EnvironmentService } from 'src/engine/integrations/environment/environment.service';
|
||||
import { OnboardingService } from 'src/engine/core-modules/onboarding/onboarding.service';
|
||||
import { LoadServiceWithWorkspaceContext } from 'src/engine/twenty-orm/context/load-service-with-workspace.context';
|
||||
import { GoogleAPIsOauthExchangeCodeForTokenGuard } from 'src/engine/core-modules/auth/guards/google-apis-oauth-exchange-code-for-token.guard';
|
||||
import { GoogleAPIsRequest } from 'src/engine/core-modules/auth/types/google-api-request.type';
|
||||
|
||||
@Controller('auth/google-apis')
|
||||
export class GoogleAPIsAuthController {
|
||||
@ -29,14 +29,14 @@ export class GoogleAPIsAuthController {
|
||||
) {}
|
||||
|
||||
@Get()
|
||||
@UseGuards(GoogleAPIsProviderEnabledGuard, GoogleAPIsOauthGuard)
|
||||
@UseGuards(GoogleAPIsOauthRequestCodeGuard)
|
||||
async googleAuth() {
|
||||
// As this method is protected by Google Auth guard, it will trigger Google SSO flow
|
||||
return;
|
||||
}
|
||||
|
||||
@Get('get-access-token')
|
||||
@UseGuards(GoogleAPIsProviderEnabledGuard, GoogleAPIsOauthGuard)
|
||||
@UseGuards(GoogleAPIsOauthExchangeCodeForTokenGuard)
|
||||
async googleAuthGetAccessToken(
|
||||
@Req() req: GoogleAPIsRequest,
|
||||
@Res() res: Response,
|
||||
@ -44,7 +44,7 @@ export class GoogleAPIsAuthController {
|
||||
const { user } = req;
|
||||
|
||||
const {
|
||||
email,
|
||||
emails,
|
||||
accessToken,
|
||||
refreshToken,
|
||||
transientToken,
|
||||
@ -68,6 +68,8 @@ export class GoogleAPIsAuthController {
|
||||
throw new Error('Workspace not found');
|
||||
}
|
||||
|
||||
const handle = emails[0].value;
|
||||
|
||||
const googleAPIsServiceInstance =
|
||||
await this.loadServiceWithWorkspaceContext.load(
|
||||
this.googleAPIsService,
|
||||
@ -75,7 +77,7 @@ export class GoogleAPIsAuthController {
|
||||
);
|
||||
|
||||
await googleAPIsServiceInstance.refreshGoogleRefreshToken({
|
||||
handle: email,
|
||||
handle,
|
||||
workspaceMemberId: workspaceMemberId,
|
||||
workspaceId: workspaceId,
|
||||
accessToken,
|
||||
|
||||
@ -0,0 +1,74 @@
|
||||
import {
|
||||
ExecutionContext,
|
||||
Injectable,
|
||||
NotFoundException,
|
||||
} from '@nestjs/common';
|
||||
import { AuthGuard } from '@nestjs/passport';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
|
||||
import { Repository } from 'typeorm';
|
||||
|
||||
import { TokenService } from 'src/engine/core-modules/auth/services/token.service';
|
||||
import {
|
||||
GoogleAPIScopeConfig,
|
||||
GoogleAPIsOauthExchangeCodeForTokenStrategy,
|
||||
} from 'src/engine/core-modules/auth/strategies/google-apis-oauth-exchange-code-for-token.auth.strategy';
|
||||
import {
|
||||
FeatureFlagEntity,
|
||||
FeatureFlagKeys,
|
||||
} from 'src/engine/core-modules/feature-flag/feature-flag.entity';
|
||||
import { EnvironmentService } from 'src/engine/integrations/environment/environment.service';
|
||||
import { setRequestExtraParams } from 'src/engine/core-modules/auth/utils/google-apis-set-request-extra-params.util';
|
||||
|
||||
@Injectable()
|
||||
export class GoogleAPIsOauthExchangeCodeForTokenGuard extends AuthGuard(
|
||||
'google-apis',
|
||||
) {
|
||||
constructor(
|
||||
private readonly environmentService: EnvironmentService,
|
||||
private readonly tokenService: TokenService,
|
||||
@InjectRepository(FeatureFlagEntity, 'core')
|
||||
private readonly featureFlagRepository: Repository<FeatureFlagEntity>,
|
||||
) {
|
||||
super();
|
||||
}
|
||||
|
||||
async canActivate(context: ExecutionContext) {
|
||||
const request = context.switchToHttp().getRequest();
|
||||
const state = JSON.parse(request.query.state);
|
||||
|
||||
if (
|
||||
!this.environmentService.get('MESSAGING_PROVIDER_GMAIL_ENABLED') &&
|
||||
!this.environmentService.get('CALENDAR_PROVIDER_GOOGLE_ENABLED')
|
||||
) {
|
||||
throw new NotFoundException('Google apis auth is not enabled');
|
||||
}
|
||||
|
||||
const { workspaceId } = await this.tokenService.verifyTransientToken(
|
||||
state.transientToken,
|
||||
);
|
||||
|
||||
const scopeConfig: GoogleAPIScopeConfig = {
|
||||
isMessagingAliasFetchingEnabled:
|
||||
!!(await this.featureFlagRepository.findOneBy({
|
||||
workspaceId,
|
||||
key: FeatureFlagKeys.IsMessagingAliasFetchingEnabled,
|
||||
value: true,
|
||||
})),
|
||||
};
|
||||
|
||||
new GoogleAPIsOauthExchangeCodeForTokenStrategy(
|
||||
this.environmentService,
|
||||
scopeConfig,
|
||||
);
|
||||
|
||||
setRequestExtraParams(request, {
|
||||
transientToken: state.transientToken,
|
||||
redirectLocation: state.redirectLocation,
|
||||
calendarVisibility: state.calendarVisibility,
|
||||
messageVisibility: state.messageVisibility,
|
||||
});
|
||||
|
||||
return (await super.canActivate(context)) as boolean;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,72 @@
|
||||
import {
|
||||
ExecutionContext,
|
||||
Injectable,
|
||||
NotFoundException,
|
||||
} from '@nestjs/common';
|
||||
import { AuthGuard } from '@nestjs/passport';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
|
||||
import { Repository } from 'typeorm';
|
||||
|
||||
import { TokenService } from 'src/engine/core-modules/auth/services/token.service';
|
||||
import { GoogleAPIScopeConfig } from 'src/engine/core-modules/auth/strategies/google-apis-oauth-exchange-code-for-token.auth.strategy';
|
||||
import {
|
||||
FeatureFlagEntity,
|
||||
FeatureFlagKeys,
|
||||
} from 'src/engine/core-modules/feature-flag/feature-flag.entity';
|
||||
import { EnvironmentService } from 'src/engine/integrations/environment/environment.service';
|
||||
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';
|
||||
|
||||
@Injectable()
|
||||
export class GoogleAPIsOauthRequestCodeGuard extends AuthGuard('google-apis') {
|
||||
constructor(
|
||||
private readonly environmentService: EnvironmentService,
|
||||
private readonly tokenService: TokenService,
|
||||
@InjectRepository(FeatureFlagEntity, 'core')
|
||||
private readonly featureFlagRepository: Repository<FeatureFlagEntity>,
|
||||
) {
|
||||
super({
|
||||
prompt: 'select_account',
|
||||
});
|
||||
}
|
||||
|
||||
async canActivate(context: ExecutionContext) {
|
||||
const request = context.switchToHttp().getRequest();
|
||||
|
||||
if (
|
||||
!this.environmentService.get('MESSAGING_PROVIDER_GMAIL_ENABLED') &&
|
||||
!this.environmentService.get('CALENDAR_PROVIDER_GOOGLE_ENABLED')
|
||||
) {
|
||||
throw new NotFoundException('Google apis auth is not enabled');
|
||||
}
|
||||
|
||||
const { workspaceId } = await this.tokenService.verifyTransientToken(
|
||||
request.query.transientToken,
|
||||
);
|
||||
|
||||
const scopeConfig: GoogleAPIScopeConfig = {
|
||||
isMessagingAliasFetchingEnabled:
|
||||
!!(await this.featureFlagRepository.findOneBy({
|
||||
workspaceId,
|
||||
key: FeatureFlagKeys.IsMessagingAliasFetchingEnabled,
|
||||
value: true,
|
||||
})),
|
||||
};
|
||||
|
||||
new GoogleAPIsOauthRequestCodeStrategy(
|
||||
this.environmentService,
|
||||
scopeConfig,
|
||||
);
|
||||
setRequestExtraParams(request, {
|
||||
transientToken: request.query.transientToken,
|
||||
redirectLocation: request.query.redirectLocation,
|
||||
calendarVisibility: request.query.calendarVisibility,
|
||||
messageVisibility: request.query.messageVisibility,
|
||||
});
|
||||
|
||||
const activate = (await super.canActivate(context)) as boolean;
|
||||
|
||||
return activate;
|
||||
}
|
||||
}
|
||||
@ -1,39 +0,0 @@
|
||||
import { ExecutionContext, Injectable } from '@nestjs/common';
|
||||
import { AuthGuard } from '@nestjs/passport';
|
||||
|
||||
@Injectable()
|
||||
export class GoogleAPIsOauthGuard extends AuthGuard('google-apis') {
|
||||
constructor() {
|
||||
super({
|
||||
prompt: 'select_account',
|
||||
});
|
||||
}
|
||||
|
||||
async canActivate(context: ExecutionContext) {
|
||||
const request = context.switchToHttp().getRequest();
|
||||
const transientToken = request.query.transientToken;
|
||||
const redirectLocation = request.query.redirectLocation;
|
||||
const calendarVisibility = request.query.calendarVisibility;
|
||||
const messageVisibility = request.query.messageVisibility;
|
||||
|
||||
if (transientToken && typeof transientToken === 'string') {
|
||||
request.params.transientToken = transientToken;
|
||||
}
|
||||
|
||||
if (redirectLocation && typeof redirectLocation === 'string') {
|
||||
request.params.redirectLocation = redirectLocation;
|
||||
}
|
||||
|
||||
if (calendarVisibility && typeof calendarVisibility === 'string') {
|
||||
request.params.calendarVisibility = calendarVisibility;
|
||||
}
|
||||
|
||||
if (messageVisibility && typeof messageVisibility === 'string') {
|
||||
request.params.messageVisibility = messageVisibility;
|
||||
}
|
||||
|
||||
const activate = (await super.canActivate(context)) as boolean;
|
||||
|
||||
return activate;
|
||||
}
|
||||
}
|
||||
@ -1,41 +0,0 @@
|
||||
import { Injectable, CanActivate, NotFoundException } from '@nestjs/common';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
|
||||
import { Repository } from 'typeorm';
|
||||
|
||||
import { TokenService } from 'src/engine/core-modules/auth/services/token.service';
|
||||
import {
|
||||
GoogleAPIScopeConfig,
|
||||
GoogleAPIsStrategy,
|
||||
} from 'src/engine/core-modules/auth/strategies/google-apis.auth.strategy';
|
||||
import { FeatureFlagEntity } from 'src/engine/core-modules/feature-flag/feature-flag.entity';
|
||||
import { EnvironmentService } from 'src/engine/integrations/environment/environment.service';
|
||||
|
||||
@Injectable()
|
||||
export class GoogleAPIsProviderEnabledGuard implements CanActivate {
|
||||
constructor(
|
||||
private readonly environmentService: EnvironmentService,
|
||||
private readonly tokenService: TokenService,
|
||||
@InjectRepository(FeatureFlagEntity, 'core')
|
||||
private readonly featureFlagRepository: Repository<FeatureFlagEntity>,
|
||||
) {}
|
||||
|
||||
async canActivate(): Promise<boolean> {
|
||||
if (
|
||||
!this.environmentService.get('MESSAGING_PROVIDER_GMAIL_ENABLED') &&
|
||||
!this.environmentService.get('CALENDAR_PROVIDER_GOOGLE_ENABLED')
|
||||
) {
|
||||
throw new NotFoundException('Google apis auth is not enabled');
|
||||
}
|
||||
|
||||
const scopeConfig: GoogleAPIScopeConfig = {
|
||||
isCalendarEnabled: !!this.environmentService.get(
|
||||
'MESSAGING_PROVIDER_GMAIL_ENABLED',
|
||||
),
|
||||
};
|
||||
|
||||
new GoogleAPIsStrategy(this.environmentService, scopeConfig);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,41 @@
|
||||
import { PassportStrategy } from '@nestjs/passport';
|
||||
import { Injectable } from '@nestjs/common';
|
||||
|
||||
import { Strategy } from 'passport-google-oauth20';
|
||||
|
||||
import { EnvironmentService } from 'src/engine/integrations/environment/environment.service';
|
||||
|
||||
export type GoogleAPIScopeConfig = {
|
||||
isCalendarEnabled?: boolean;
|
||||
isMessagingAliasFetchingEnabled?: boolean;
|
||||
};
|
||||
|
||||
@Injectable()
|
||||
export class GoogleAPIsOauthCommonStrategy extends PassportStrategy(
|
||||
Strategy,
|
||||
'google-apis',
|
||||
) {
|
||||
constructor(
|
||||
environmentService: EnvironmentService,
|
||||
scopeConfig: GoogleAPIScopeConfig,
|
||||
) {
|
||||
const scopes = [
|
||||
'email',
|
||||
'profile',
|
||||
'https://www.googleapis.com/auth/gmail.readonly',
|
||||
'https://www.googleapis.com/auth/calendar.events',
|
||||
];
|
||||
|
||||
if (scopeConfig?.isMessagingAliasFetchingEnabled) {
|
||||
scopes.push('https://www.googleapis.com/auth/profile.emails.read');
|
||||
}
|
||||
|
||||
super({
|
||||
clientID: environmentService.get('AUTH_GOOGLE_CLIENT_ID'),
|
||||
clientSecret: environmentService.get('AUTH_GOOGLE_CLIENT_SECRET'),
|
||||
callbackURL: environmentService.get('AUTH_GOOGLE_APIS_CALLBACK_URL'),
|
||||
scope: scopes,
|
||||
passReqToCallback: true,
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,52 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
|
||||
import { VerifyCallback } from 'passport-google-oauth20';
|
||||
|
||||
import { GoogleAPIsOauthCommonStrategy } from 'src/engine/core-modules/auth/strategies/google-apis-oauth-common.auth.strategy';
|
||||
import { EnvironmentService } from 'src/engine/integrations/environment/environment.service';
|
||||
import { GoogleAPIsRequest } from 'src/engine/core-modules/auth/types/google-api-request.type';
|
||||
|
||||
export type GoogleAPIScopeConfig = {
|
||||
isCalendarEnabled?: boolean;
|
||||
isMessagingAliasFetchingEnabled?: boolean;
|
||||
};
|
||||
|
||||
@Injectable()
|
||||
export class GoogleAPIsOauthExchangeCodeForTokenStrategy extends GoogleAPIsOauthCommonStrategy {
|
||||
constructor(
|
||||
environmentService: EnvironmentService,
|
||||
scopeConfig: GoogleAPIScopeConfig,
|
||||
) {
|
||||
super(environmentService, scopeConfig);
|
||||
}
|
||||
|
||||
async validate(
|
||||
request: GoogleAPIsRequest,
|
||||
accessToken: string,
|
||||
refreshToken: string,
|
||||
profile: any,
|
||||
done: VerifyCallback,
|
||||
): Promise<void> {
|
||||
const { name, emails, photos } = profile;
|
||||
|
||||
const state =
|
||||
typeof request.query.state === 'string'
|
||||
? JSON.parse(request.query.state)
|
||||
: undefined;
|
||||
|
||||
const user: GoogleAPIsRequest['user'] = {
|
||||
emails,
|
||||
firstName: name.givenName,
|
||||
lastName: name.familyName,
|
||||
picture: photos?.[0]?.value,
|
||||
accessToken,
|
||||
refreshToken,
|
||||
transientToken: state.transientToken,
|
||||
redirectLocation: state.redirectLocation,
|
||||
calendarVisibility: state.calendarVisibility,
|
||||
messageVisibility: state.messageVisibility,
|
||||
};
|
||||
|
||||
done(null, user);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,35 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
|
||||
import { GoogleAPIsOauthCommonStrategy } from 'src/engine/core-modules/auth/strategies/google-apis-oauth-common.auth.strategy';
|
||||
import { EnvironmentService } from 'src/engine/integrations/environment/environment.service';
|
||||
|
||||
export type GoogleAPIScopeConfig = {
|
||||
isCalendarEnabled?: boolean;
|
||||
isMessagingAliasFetchingEnabled?: boolean;
|
||||
};
|
||||
|
||||
@Injectable()
|
||||
export class GoogleAPIsOauthRequestCodeStrategy extends GoogleAPIsOauthCommonStrategy {
|
||||
constructor(
|
||||
environmentService: EnvironmentService,
|
||||
scopeConfig: GoogleAPIScopeConfig,
|
||||
) {
|
||||
super(environmentService, scopeConfig);
|
||||
}
|
||||
|
||||
authenticate(req: any, options: any) {
|
||||
options = {
|
||||
...options,
|
||||
accessType: 'offline',
|
||||
prompt: 'consent',
|
||||
state: JSON.stringify({
|
||||
transientToken: req.params.transientToken,
|
||||
redirectLocation: req.params.redirectLocation,
|
||||
calendarVisibility: req.params.calendarVisibility,
|
||||
messageVisibility: req.params.messageVisibility,
|
||||
}),
|
||||
};
|
||||
|
||||
return super.authenticate(req, options);
|
||||
}
|
||||
}
|
||||
@ -1,110 +0,0 @@
|
||||
import { PassportStrategy } from '@nestjs/passport';
|
||||
import { Injectable } from '@nestjs/common';
|
||||
|
||||
import { Strategy, VerifyCallback } from 'passport-google-oauth20';
|
||||
import { Request } from 'express';
|
||||
|
||||
import { EnvironmentService } from 'src/engine/integrations/environment/environment.service';
|
||||
import { CalendarChannelVisibility } from 'src/modules/calendar/standard-objects/calendar-channel.workspace-entity';
|
||||
import { MessageChannelVisibility } from 'src/modules/messaging/common/standard-objects/message-channel.workspace-entity';
|
||||
|
||||
export type GoogleAPIsRequest = Omit<
|
||||
Request,
|
||||
'user' | 'workspace' | 'cacheVersion'
|
||||
> & {
|
||||
user: {
|
||||
firstName?: string | null;
|
||||
lastName?: string | null;
|
||||
email: string;
|
||||
picture: string | null;
|
||||
workspaceInviteHash?: string;
|
||||
accessToken: string;
|
||||
refreshToken: string;
|
||||
transientToken: string;
|
||||
redirectLocation?: string;
|
||||
calendarVisibility?: CalendarChannelVisibility;
|
||||
messageVisibility?: MessageChannelVisibility;
|
||||
};
|
||||
};
|
||||
|
||||
export type GoogleAPIScopeConfig = {
|
||||
isCalendarEnabled?: boolean;
|
||||
};
|
||||
|
||||
@Injectable()
|
||||
export class GoogleAPIsStrategy extends PassportStrategy(
|
||||
Strategy,
|
||||
'google-apis',
|
||||
) {
|
||||
constructor(
|
||||
environmentService: EnvironmentService,
|
||||
scopeConfig: GoogleAPIScopeConfig,
|
||||
) {
|
||||
const scope = ['email', 'profile'];
|
||||
|
||||
if (environmentService.get('MESSAGING_PROVIDER_GMAIL_ENABLED')) {
|
||||
scope.push('https://www.googleapis.com/auth/gmail.readonly');
|
||||
}
|
||||
|
||||
if (
|
||||
environmentService.get('CALENDAR_PROVIDER_GOOGLE_ENABLED') &&
|
||||
scopeConfig?.isCalendarEnabled
|
||||
) {
|
||||
scope.push('https://www.googleapis.com/auth/calendar.events');
|
||||
}
|
||||
|
||||
super({
|
||||
clientID: environmentService.get('AUTH_GOOGLE_CLIENT_ID'),
|
||||
clientSecret: environmentService.get('AUTH_GOOGLE_CLIENT_SECRET'),
|
||||
callbackURL: environmentService.get('AUTH_GOOGLE_APIS_CALLBACK_URL'),
|
||||
scope,
|
||||
passReqToCallback: true,
|
||||
});
|
||||
}
|
||||
|
||||
authenticate(req: any, options: any) {
|
||||
options = {
|
||||
...options,
|
||||
accessType: 'offline',
|
||||
prompt: 'consent',
|
||||
state: JSON.stringify({
|
||||
transientToken: req.params.transientToken,
|
||||
redirectLocation: req.params.redirectLocation,
|
||||
calendarVisibility: req.params.calendarVisibility,
|
||||
messageVisibility: req.params.messageVisibility,
|
||||
}),
|
||||
};
|
||||
|
||||
return super.authenticate(req, options);
|
||||
}
|
||||
|
||||
async validate(
|
||||
request: GoogleAPIsRequest,
|
||||
accessToken: string,
|
||||
refreshToken: string,
|
||||
profile: any,
|
||||
done: VerifyCallback,
|
||||
): Promise<void> {
|
||||
const { name, emails, photos } = profile;
|
||||
|
||||
const state =
|
||||
typeof request.query.state === 'string'
|
||||
? JSON.parse(request.query.state)
|
||||
: undefined;
|
||||
|
||||
const user: GoogleAPIsRequest['user'] = {
|
||||
email: emails[0].value,
|
||||
firstName: name.givenName,
|
||||
lastName: name.familyName,
|
||||
picture: photos?.[0]?.value,
|
||||
accessToken,
|
||||
refreshToken,
|
||||
transientToken: state.transientToken,
|
||||
redirectLocation: state.redirectLocation,
|
||||
calendarVisibility: state.calendarVisibility,
|
||||
messageVisibility: state.messageVisibility,
|
||||
};
|
||||
|
||||
done(null, user);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,23 @@
|
||||
import { Request } from 'express';
|
||||
|
||||
import { CalendarChannelVisibility } from 'src/modules/calendar/standard-objects/calendar-channel.workspace-entity';
|
||||
import { MessageChannelVisibility } from 'src/modules/messaging/common/standard-objects/message-channel.workspace-entity';
|
||||
|
||||
export type GoogleAPIsRequest = Omit<
|
||||
Request,
|
||||
'user' | 'workspace' | 'cacheVersion'
|
||||
> & {
|
||||
user: {
|
||||
firstName?: string | null;
|
||||
lastName?: string | null;
|
||||
emails: { value: string }[];
|
||||
picture: string | null;
|
||||
workspaceInviteHash?: string;
|
||||
accessToken: string;
|
||||
refreshToken: string;
|
||||
transientToken: string;
|
||||
redirectLocation?: string;
|
||||
calendarVisibility?: CalendarChannelVisibility;
|
||||
messageVisibility?: MessageChannelVisibility;
|
||||
};
|
||||
};
|
||||
@ -0,0 +1,40 @@
|
||||
import { GoogleAPIsRequest } from 'src/engine/core-modules/auth/types/google-api-request.type';
|
||||
import { setRequestExtraParams } from 'src/engine/core-modules/auth/utils/google-apis-set-request-extra-params.util';
|
||||
import { CalendarChannelVisibility } from 'src/modules/calendar/standard-objects/calendar-channel.workspace-entity';
|
||||
import { MessageChannelVisibility } from 'src/modules/messaging/common/standard-objects/message-channel.workspace-entity';
|
||||
|
||||
describe('googleApisSetRequestExtraParams', () => {
|
||||
it('should set request extra params', () => {
|
||||
const request = {
|
||||
params: {},
|
||||
} as GoogleAPIsRequest;
|
||||
|
||||
setRequestExtraParams(request, {
|
||||
transientToken: 'abc',
|
||||
redirectLocation: '/test',
|
||||
calendarVisibility: CalendarChannelVisibility.SHARE_EVERYTHING,
|
||||
messageVisibility: MessageChannelVisibility.SHARE_EVERYTHING,
|
||||
});
|
||||
|
||||
expect(request.params).toEqual({
|
||||
transientToken: 'abc',
|
||||
redirectLocation: '/test',
|
||||
calendarVisibility: CalendarChannelVisibility.SHARE_EVERYTHING,
|
||||
messageVisibility: MessageChannelVisibility.SHARE_EVERYTHING,
|
||||
});
|
||||
});
|
||||
|
||||
it('should throw error if transientToken is not provided', () => {
|
||||
const request = {
|
||||
params: {},
|
||||
} as GoogleAPIsRequest;
|
||||
|
||||
expect(() => {
|
||||
setRequestExtraParams(request, {
|
||||
redirectLocation: '/test',
|
||||
calendarVisibility: CalendarChannelVisibility.SHARE_EVERYTHING,
|
||||
messageVisibility: MessageChannelVisibility.SHARE_EVERYTHING,
|
||||
});
|
||||
}).toThrow('transientToken is required');
|
||||
});
|
||||
});
|
||||
@ -0,0 +1,38 @@
|
||||
import { GoogleAPIsRequest } from 'src/engine/core-modules/auth/types/google-api-request.type';
|
||||
|
||||
type GoogleAPIsRequestExtraParams = {
|
||||
transientToken?: string;
|
||||
redirectLocation?: string;
|
||||
calendarVisibility?: string;
|
||||
messageVisibility?: string;
|
||||
};
|
||||
|
||||
export const setRequestExtraParams = (
|
||||
request: GoogleAPIsRequest,
|
||||
params: GoogleAPIsRequestExtraParams,
|
||||
): void => {
|
||||
const {
|
||||
transientToken,
|
||||
redirectLocation,
|
||||
calendarVisibility,
|
||||
messageVisibility,
|
||||
} = params;
|
||||
|
||||
if (!transientToken) {
|
||||
throw new Error('transientToken is required');
|
||||
}
|
||||
|
||||
request.params.transientToken = transientToken;
|
||||
|
||||
if (redirectLocation) {
|
||||
request.params.redirectLocation = redirectLocation;
|
||||
}
|
||||
|
||||
if (calendarVisibility) {
|
||||
request.params.calendarVisibility = calendarVisibility;
|
||||
}
|
||||
|
||||
if (messageVisibility) {
|
||||
request.params.messageVisibility = messageVisibility;
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user