5622 add a syncemail onboarding step (#5689)
- add sync email onboarding step - refactor calendar and email visibility enums - add a new table `keyValuePair` in `core` schema - add a new resolved boolean field `skipSyncEmail` in current user https://github.com/twentyhq/twenty/assets/29927851/de791475-5bfe-47f9-8e90-76c349fba56f
This commit is contained in:
@ -27,6 +27,7 @@ import { ObjectMetadataRepositoryModule } from 'src/engine/object-metadata-repos
|
||||
import { ConnectedAccountWorkspaceEntity } from 'src/modules/connected-account/standard-objects/connected-account.workspace-entity';
|
||||
import { CalendarChannelWorkspaceEntity } from 'src/modules/calendar/standard-objects/calendar-channel.workspace-entity';
|
||||
import { MessageChannelWorkspaceEntity } from 'src/modules/messaging/common/standard-objects/message-channel.workspace-entity';
|
||||
import { UserStateModule } from 'src/engine/core-modules/user-state/user-state.module';
|
||||
|
||||
import { AuthResolver } from './auth.resolver';
|
||||
|
||||
@ -63,6 +64,7 @@ const jwtModule = JwtModule.registerAsync({
|
||||
]),
|
||||
HttpModule,
|
||||
UserWorkspaceModule,
|
||||
UserStateModule,
|
||||
],
|
||||
controllers: [
|
||||
GoogleAuthController,
|
||||
|
||||
@ -15,6 +15,10 @@ import { GoogleAPIsRequest } from 'src/engine/core-modules/auth/strategies/googl
|
||||
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 { UserStateService } from 'src/engine/core-modules/user-state/user-state.service';
|
||||
import { InjectObjectMetadataRepository } from 'src/engine/object-metadata-repository/object-metadata-repository.decorator';
|
||||
import { WorkspaceMemberWorkspaceEntity } from 'src/modules/workspace-member/standard-objects/workspace-member.workspace-entity';
|
||||
import { WorkspaceMemberRepository } from 'src/modules/workspace-member/repositories/workspace-member.repository';
|
||||
|
||||
@Controller('auth/google-apis')
|
||||
export class GoogleAPIsAuthController {
|
||||
@ -22,6 +26,9 @@ export class GoogleAPIsAuthController {
|
||||
private readonly googleAPIsService: GoogleAPIsService,
|
||||
private readonly tokenService: TokenService,
|
||||
private readonly environmentService: EnvironmentService,
|
||||
private readonly userStateService: UserStateService,
|
||||
@InjectObjectMetadataRepository(WorkspaceMemberWorkspaceEntity)
|
||||
private readonly workspaceMemberService: WorkspaceMemberRepository,
|
||||
) {}
|
||||
|
||||
@Get()
|
||||
@ -39,7 +46,15 @@ export class GoogleAPIsAuthController {
|
||||
) {
|
||||
const { user } = req;
|
||||
|
||||
const { email, accessToken, refreshToken, transientToken } = user;
|
||||
const {
|
||||
email,
|
||||
accessToken,
|
||||
refreshToken,
|
||||
transientToken,
|
||||
redirectLocation,
|
||||
calendarVisibility,
|
||||
messageVisibility,
|
||||
} = user;
|
||||
|
||||
const { workspaceMemberId, workspaceId } =
|
||||
await this.tokenService.verifyTransientToken(transientToken);
|
||||
@ -62,10 +77,25 @@ export class GoogleAPIsAuthController {
|
||||
workspaceId: workspaceId,
|
||||
accessToken,
|
||||
refreshToken,
|
||||
calendarVisibility,
|
||||
messageVisibility,
|
||||
});
|
||||
|
||||
const userId = (
|
||||
await this.workspaceMemberService.find(workspaceMemberId, workspaceId)
|
||||
)?.userId;
|
||||
|
||||
if (userId) {
|
||||
await this.userStateService.skipSyncEmailOnboardingStep(
|
||||
userId,
|
||||
workspaceId,
|
||||
);
|
||||
}
|
||||
|
||||
return res.redirect(
|
||||
`${this.environmentService.get('FRONT_BASE_URL')}/settings/accounts`,
|
||||
`${this.environmentService.get('FRONT_BASE_URL')}${
|
||||
redirectLocation || '/settings/accounts'
|
||||
}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -12,10 +12,26 @@ export class GoogleAPIsOauthGuard extends AuthGuard('google-apis') {
|
||||
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;
|
||||
|
||||
@ -58,8 +58,16 @@ export class GoogleAPIsService {
|
||||
workspaceId: string;
|
||||
accessToken: string;
|
||||
refreshToken: string;
|
||||
calendarVisibility: CalendarChannelVisibility | undefined;
|
||||
messageVisibility: MessageChannelVisibility | undefined;
|
||||
}) {
|
||||
const { handle, workspaceId, workspaceMemberId } = input;
|
||||
const {
|
||||
handle,
|
||||
workspaceId,
|
||||
workspaceMemberId,
|
||||
calendarVisibility,
|
||||
messageVisibility,
|
||||
} = input;
|
||||
|
||||
const dataSourceMetadata =
|
||||
await this.dataSourceService.getLastDataSourceMetadataFromWorkspaceIdOrFail(
|
||||
@ -104,7 +112,8 @@ export class GoogleAPIsService {
|
||||
connectedAccountId: newOrExistingConnectedAccountId,
|
||||
type: MessageChannelType.EMAIL,
|
||||
handle,
|
||||
visibility: MessageChannelVisibility.SHARE_EVERYTHING,
|
||||
visibility:
|
||||
messageVisibility || MessageChannelVisibility.SHARE_EVERYTHING,
|
||||
},
|
||||
workspaceId,
|
||||
manager,
|
||||
@ -116,7 +125,9 @@ export class GoogleAPIsService {
|
||||
id: v4(),
|
||||
connectedAccountId: newOrExistingConnectedAccountId,
|
||||
handle,
|
||||
visibility: CalendarChannelVisibility.SHARE_EVERYTHING,
|
||||
visibility:
|
||||
calendarVisibility ||
|
||||
CalendarChannelVisibility.SHARE_EVERYTHING,
|
||||
},
|
||||
workspaceId,
|
||||
manager,
|
||||
|
||||
@ -5,6 +5,8 @@ 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,
|
||||
@ -19,6 +21,9 @@ export type GoogleAPIsRequest = Omit<
|
||||
accessToken: string;
|
||||
refreshToken: string;
|
||||
transientToken: string;
|
||||
redirectLocation?: string;
|
||||
calendarVisibility?: CalendarChannelVisibility;
|
||||
messageVisibility?: MessageChannelVisibility;
|
||||
};
|
||||
};
|
||||
|
||||
@ -64,6 +69,9 @@ export class GoogleAPIsStrategy extends PassportStrategy(
|
||||
prompt: 'consent',
|
||||
state: JSON.stringify({
|
||||
transientToken: req.params.transientToken,
|
||||
redirectLocation: req.params.redirectLocation,
|
||||
calendarVisibility: req.params.calendarVisibility,
|
||||
messageVisibility: req.params.messageVisibility,
|
||||
}),
|
||||
};
|
||||
|
||||
@ -92,6 +100,9 @@ export class GoogleAPIsStrategy extends PassportStrategy(
|
||||
accessToken,
|
||||
refreshToken,
|
||||
transientToken: state.transientToken,
|
||||
redirectLocation: state.redirectLocation,
|
||||
calendarVisibility: state.calendarVisibility,
|
||||
messageVisibility: state.messageVisibility,
|
||||
};
|
||||
|
||||
done(null, user);
|
||||
|
||||
Reference in New Issue
Block a user