Pass Billing Checkout var in url to bypass credit card (#9283)

This commit is contained in:
Félix Malfait
2024-12-31 14:48:00 +01:00
committed by GitHub
parent 45f14c8020
commit 97f5a5b8a5
123 changed files with 524 additions and 173 deletions

View File

@ -8,9 +8,10 @@ import {
} from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { Response } from 'express';
import { Repository } from 'typeorm';
import { AuthException } from 'src/engine/core-modules/auth/auth.exception';
import { AuthOAuthExceptionFilter } from 'src/engine/core-modules/auth/filters/auth-oauth-exception.filter';
import { AuthRestApiExceptionFilter } from 'src/engine/core-modules/auth/filters/auth-rest-api-exception.filter';
import { GoogleOauthGuard } from 'src/engine/core-modules/auth/guards/google-oauth.guard';
@ -18,9 +19,8 @@ import { GoogleProviderEnabledGuard } from 'src/engine/core-modules/auth/guards/
import { AuthService } from 'src/engine/core-modules/auth/services/auth.service';
import { GoogleRequest } from 'src/engine/core-modules/auth/strategies/google.auth.strategy';
import { LoginTokenService } from 'src/engine/core-modules/auth/token/services/login-token.service';
import { AuthException } from 'src/engine/core-modules/auth/auth.exception';
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
import { DomainManagerService } from 'src/engine/core-modules/domain-manager/service/domain-manager.service';
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
@Controller('auth/google')
@ -55,6 +55,7 @@ export class GoogleAuthController {
workspaceInviteHash,
workspacePersonalInviteToken,
targetWorkspaceSubdomain,
billingCheckoutSessionState,
} = req.user;
const signInUpParams = {
@ -106,6 +107,7 @@ export class GoogleAuthController {
this.authService.computeRedirectURI(
loginToken.token,
workspace.subdomain,
billingCheckoutSessionState,
),
);
} catch (err) {

View File

@ -11,15 +11,15 @@ import { InjectRepository } from '@nestjs/typeorm';
import { Response } from 'express';
import { Repository } from 'typeorm';
import { AuthException } from 'src/engine/core-modules/auth/auth.exception';
import { AuthRestApiExceptionFilter } from 'src/engine/core-modules/auth/filters/auth-rest-api-exception.filter';
import { MicrosoftOAuthGuard } from 'src/engine/core-modules/auth/guards/microsoft-oauth.guard';
import { MicrosoftProviderEnabledGuard } from 'src/engine/core-modules/auth/guards/microsoft-provider-enabled.guard';
import { AuthService } from 'src/engine/core-modules/auth/services/auth.service';
import { MicrosoftRequest } from 'src/engine/core-modules/auth/strategies/microsoft.auth.strategy';
import { LoginTokenService } from 'src/engine/core-modules/auth/token/services/login-token.service';
import { AuthException } from 'src/engine/core-modules/auth/auth.exception';
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
import { DomainManagerService } from 'src/engine/core-modules/domain-manager/service/domain-manager.service';
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
@Controller('auth/microsoft')
@ -90,6 +90,7 @@ export class MicrosoftAuthController {
this.authService.computeRedirectURI(
loginToken.token,
workspace.subdomain,
signInUpParams.billingCheckoutSessionState,
),
);
} catch (err) {

View File

@ -45,6 +45,14 @@ export class GoogleOauthGuard extends AuthGuard('google') {
request.params.workspaceSubdomain = request.query.workspaceSubdomain;
}
if (
request.query.billingCheckoutSessionState &&
typeof request.query.billingCheckoutSessionState === 'string'
) {
request.params.billingCheckoutSessionState =
request.query.billingCheckoutSessionState;
}
return (await super.canActivate(context)) as boolean;
}
}

View File

@ -33,6 +33,14 @@ export class MicrosoftOAuthGuard extends AuthGuard('microsoft') {
request.params.workspaceSubdomain = request.query.workspaceSubdomain;
}
if (
request.query.billingCheckoutSessionState &&
typeof request.query.billingCheckoutSessionState === 'string'
) {
request.params.billingCheckoutSessionState =
request.query.billingCheckoutSessionState;
}
return (await super.canActivate(context)) as boolean;
}
}

View File

@ -28,6 +28,7 @@ import { AuthorizeApp } from 'src/engine/core-modules/auth/dto/authorize-app.ent
import { AuthorizeAppInput } from 'src/engine/core-modules/auth/dto/authorize-app.input';
import { AvailableWorkspaceOutput } from 'src/engine/core-modules/auth/dto/available-workspaces.output';
import { ChallengeInput } from 'src/engine/core-modules/auth/dto/challenge.input';
import { AuthTokens } from 'src/engine/core-modules/auth/dto/token.entity';
import { UpdatePassword } from 'src/engine/core-modules/auth/dto/update-password.entity';
import {
UserExists,
@ -46,7 +47,6 @@ import { userValidator } from 'src/engine/core-modules/user/user.validate';
import { WorkspaceInvitationService } from 'src/engine/core-modules/workspace-invitation/services/workspace-invitation.service';
import { WorkspaceAuthProvider } from 'src/engine/core-modules/workspace/types/workspace.type';
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
import { AuthTokens } from 'src/engine/core-modules/auth/dto/token.entity';
@Injectable()
// eslint-disable-next-line @nx/workspace-inject-workspace-repository
@ -171,6 +171,7 @@ export class AuthService {
fromSSO: boolean;
targetWorkspaceSubdomain?: string;
authProvider?: WorkspaceAuthProvider;
billingCheckoutSessionState?: string;
}) {
return await this.signInUpService.signInUp({
email,
@ -413,11 +414,18 @@ export class AuthService {
return workspace;
}
computeRedirectURI(loginToken: string, subdomain?: string) {
computeRedirectURI(
loginToken: string,
subdomain?: string,
billingCheckoutSessionState?: string,
) {
const url = this.domainManagerService.buildWorkspaceURL({
subdomain,
pathname: '/verify',
searchParams: { loginToken },
searchParams: {
loginToken,
...(billingCheckoutSessionState ? { billingCheckoutSessionState } : {}),
},
});
return url.toString();

View File

@ -35,8 +35,8 @@ import {
import { workspaceValidator } from 'src/engine/core-modules/workspace/workspace.validate';
import { getDomainNameByEmail } from 'src/utils/get-domain-name-by-email';
import { getImageBufferFromUrl } from 'src/utils/image';
import { isWorkEmail } from 'src/utils/is-work-email';
import { isDefined } from 'src/utils/is-defined';
import { isWorkEmail } from 'src/utils/is-work-email';
export type SignInUpServiceInput = {
email: string;

View File

@ -18,6 +18,7 @@ export type GoogleRequest = Omit<
workspaceInviteHash?: string;
workspacePersonalInviteToken?: string;
targetWorkspaceSubdomain?: string;
billingCheckoutSessionState?: string;
};
};
@ -39,6 +40,12 @@ export class GoogleStrategy extends PassportStrategy(Strategy, 'google') {
state: JSON.stringify({
workspaceInviteHash: req.params.workspaceInviteHash,
workspaceSubdomain: req.params.workspaceSubdomain,
...(req.params.billingCheckoutSessionState
? {
billingCheckoutSessionState:
req.params.billingCheckoutSessionState,
}
: {}),
...(req.params.workspacePersonalInviteToken
? {
workspacePersonalInviteToken:
@ -72,6 +79,7 @@ export class GoogleStrategy extends PassportStrategy(Strategy, 'google') {
workspaceInviteHash: state.workspaceInviteHash,
workspacePersonalInviteToken: state.workspacePersonalInviteToken,
targetWorkspaceSubdomain: state.workspaceSubdomain,
billingCheckoutSessionState: state.billingCheckoutSessionState,
};
done(null, user);

View File

@ -22,6 +22,7 @@ export type MicrosoftRequest = Omit<
workspaceInviteHash?: string;
workspacePersonalInviteToken?: string;
targetWorkspaceSubdomain?: string;
billingCheckoutSessionState?: string;
};
};
@ -43,6 +44,12 @@ export class MicrosoftStrategy extends PassportStrategy(Strategy, 'microsoft') {
state: JSON.stringify({
workspaceInviteHash: req.params.workspaceInviteHash,
workspaceSubdomain: req.params.workspaceSubdomain,
...(req.params.billingCheckoutSessionState
? {
billingCheckoutSessionState:
req.params.billingCheckoutSessionState,
}
: {}),
...(req.params.workspacePersonalInviteToken
? {
workspacePersonalInviteToken:
@ -86,6 +93,7 @@ export class MicrosoftStrategy extends PassportStrategy(Strategy, 'microsoft') {
workspaceInviteHash: state.workspaceInviteHash,
workspacePersonalInviteToken: state.workspacePersonalInviteToken,
targetWorkspaceSubdomain: state.workspaceSubdomain,
billingCheckoutSessionState: state.billingCheckoutSessionState,
};
done(null, user);