implemented comments

This commit is contained in:
Sheen Capadngan
2023-05-03 18:58:32 +08:00
parent dfb84e9932
commit f703ee29e5
16 changed files with 247 additions and 151 deletions
+2 -2
View File
@@ -70,6 +70,6 @@ STRIPE_PRODUCT_TEAM=
STRIPE_PRODUCT_PRO= STRIPE_PRODUCT_PRO=
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY= NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=
GOOGLE_CLIENT_ID= CLIENT_ID_GOOGLE=
GOOGLE_CLIENT_SECRET= CLIENT_SECRET_GOOGLE=
SESSION_SECRET= SESSION_SECRET=
+2
View File
@@ -29,12 +29,14 @@ export const getClientIdVercel = async () => (await client.getSecret('CLIENT_ID_
export const getClientIdNetlify = async () => (await client.getSecret('CLIENT_ID_NETLIFY')).secretValue; export const getClientIdNetlify = async () => (await client.getSecret('CLIENT_ID_NETLIFY')).secretValue;
export const getClientIdGitHub = async () => (await client.getSecret('CLIENT_ID_GITHUB')).secretValue; export const getClientIdGitHub = async () => (await client.getSecret('CLIENT_ID_GITHUB')).secretValue;
export const getClientIdGitLab = async () => (await client.getSecret('CLIENT_ID_GITLAB')).secretValue; export const getClientIdGitLab = async () => (await client.getSecret('CLIENT_ID_GITLAB')).secretValue;
export const getClientIdGoogle = async () => (await client.getSecret('CLIENT_ID_GOOGLE')).secretValue;
export const getClientSecretAzure = async () => (await client.getSecret('CLIENT_SECRET_AZURE')).secretValue; export const getClientSecretAzure = async () => (await client.getSecret('CLIENT_SECRET_AZURE')).secretValue;
export const getClientSecretHeroku = async () => (await client.getSecret('CLIENT_SECRET_HEROKU')).secretValue; export const getClientSecretHeroku = async () => (await client.getSecret('CLIENT_SECRET_HEROKU')).secretValue;
export const getClientSecretVercel = async () => (await client.getSecret('CLIENT_SECRET_VERCEL')).secretValue; export const getClientSecretVercel = async () => (await client.getSecret('CLIENT_SECRET_VERCEL')).secretValue;
export const getClientSecretNetlify = async () => (await client.getSecret('CLIENT_SECRET_NETLIFY')).secretValue; export const getClientSecretNetlify = async () => (await client.getSecret('CLIENT_SECRET_NETLIFY')).secretValue;
export const getClientSecretGitHub = async () => (await client.getSecret('CLIENT_SECRET_GITHUB')).secretValue; export const getClientSecretGitHub = async () => (await client.getSecret('CLIENT_SECRET_GITHUB')).secretValue;
export const getClientSecretGitLab = async () => (await client.getSecret('CLIENT_SECRET_GITLAB')).secretValue; export const getClientSecretGitLab = async () => (await client.getSecret('CLIENT_SECRET_GITLAB')).secretValue;
export const getClientSecretGoogle = async () => (await client.getSecret('CLIENT_SECRET_GOOGLE')).secretValue;
export const getClientSlugVercel = async () => (await client.getSecret('CLIENT_SLUG_VERCEL')).secretValue; export const getClientSlugVercel = async () => (await client.getSecret('CLIENT_SLUG_VERCEL')).secretValue;
export const getPostHogHost = async () => (await client.getSecret('POSTHOG_HOST')).secretValue || 'https://app.posthog.com'; export const getPostHogHost = async () => (await client.getSecret('POSTHOG_HOST')).secretValue || 'https://app.posthog.com';
export const getPostHogProjectApiKey = async () => (await client.getSecret('POSTHOG_PROJECT_API_KEY')).secretValue || 'phc_nSin8j5q2zdhpFDI1ETmFNUIuTG4DwKVyIigrY10XiE'; export const getPostHogProjectApiKey = async () => (await client.getSecret('POSTHOG_PROJECT_API_KEY')).secretValue || 'phc_nSin8j5q2zdhpFDI1ETmFNUIuTG4DwKVyIigrY10XiE';
@@ -267,7 +267,3 @@ export const getNewToken = async (req: Request, res: Response) => {
}); });
} }
}; };
export const handleGoogleCallback = (req: Request, res: Response) => {
res.redirect(`/login/provider/success?token=${encodeURIComponent(req.providerAuthToken)}`);
}
+2
View File
@@ -5,6 +5,7 @@ import * as integrationController from './integrationController';
import * as keyController from './keyController'; import * as keyController from './keyController';
import * as membershipController from './membershipController'; import * as membershipController from './membershipController';
import * as membershipOrgController from './membershipOrgController'; import * as membershipOrgController from './membershipOrgController';
import * as oauthController from './oauthController';
import * as organizationController from './organizationController'; import * as organizationController from './organizationController';
import * as passwordController from './passwordController'; import * as passwordController from './passwordController';
import * as secretController from './secretController'; import * as secretController from './secretController';
@@ -23,6 +24,7 @@ export {
keyController, keyController,
membershipController, membershipController,
membershipOrgController, membershipOrgController,
oauthController,
organizationController, organizationController,
passwordController, passwordController,
secretController, secretController,
@@ -0,0 +1,5 @@
import { Request, Response } from 'express';
export const handleAuthProviderCallback = (req: Request, res: Response) => {
res.redirect(`/login/provider/success?token=${encodeURIComponent(req.providerAuthToken)}`);
}
+29 -46
View File
@@ -5,7 +5,7 @@ import * as Sentry from '@sentry/node';
import * as bigintConversion from 'bigint-conversion'; import * as bigintConversion from 'bigint-conversion';
const jsrp = require('jsrp'); const jsrp = require('jsrp');
import { User, LoginSRPDetail } from '../../models'; import { User, LoginSRPDetail } from '../../models';
import { issueAuthTokens, createToken } from '../../helpers/auth'; import { issueAuthTokens, createToken, validateProviderAuthToken } from '../../helpers/auth';
import { checkUserDevice } from '../../helpers/user'; import { checkUserDevice } from '../../helpers/user';
import { sendMail } from '../../helpers/nodemailer'; import { sendMail } from '../../helpers/nodemailer';
import { TokenService } from '../../services'; import { TokenService } from '../../services';
@@ -20,12 +20,14 @@ import {
getJwtMfaLifetime, getJwtMfaLifetime,
getJwtMfaSecret, getJwtMfaSecret,
getHttpsEnabled, getHttpsEnabled,
getJwtProviderAuthSecret
} from '../../config'; } from '../../config';
import { AuthProvider } from '../../models/user';
declare module 'jsonwebtoken' { declare module 'jsonwebtoken' {
export interface ProviderAuthJwtPayload extends jwt.JwtPayload { export interface ProviderAuthJwtPayload extends jwt.JwtPayload {
userId: string; userId: string;
email: string;
authProvider: AuthProvider;
} }
} }
@@ -42,30 +44,25 @@ export const login1 = async (req: Request, res: Response) => {
providerAuthToken, providerAuthToken,
clientPublicKey clientPublicKey
}: { }: {
email?: string; email: string;
clientPublicKey: string, clientPublicKey: string,
providerAuthToken?: string; providerAuthToken?: string;
} = req.body; } = req.body;
let userId = ''; const user = await User.findOne({
if (providerAuthToken) {
const decodedToken = <jwt.ProviderAuthJwtPayload>(
jwt.verify(providerAuthToken, await getJwtProviderAuthSecret())
);
userId = decodedToken.userId;
}
const filter = userId ? {
_id: userId,
} : {
email, email,
} }).select('+salt +verifier');
const user = await User.findOne(filter).select('+salt +verifier');
if (!user) throw new Error('Failed to find user'); if (!user) throw new Error('Failed to find user');
if (user.authProvider) {
await validateProviderAuthToken({
email,
user,
providerAuthToken,
})
}
const server = new jsrp.server(); const server = new jsrp.server();
server.init( server.init(
{ {
@@ -75,14 +72,10 @@ export const login1 = async (req: Request, res: Response) => {
async () => { async () => {
// generate server-side public key // generate server-side public key
const serverPublicKey = server.getPublicKey(); const serverPublicKey = server.getPublicKey();
const identifier = userId ? { await LoginSRPDetail.findOneAndReplace({
userId, userId: user.id,
} : { }, {
email, userId: user.id,
}
await LoginSRPDetail.findOneAndReplace(filter, {
...identifier,
clientPublicKey: clientPublicKey, clientPublicKey: clientPublicKey,
serverBInt: bigintConversion.bigintToBuf(server.bInt), serverBInt: bigintConversion.bigintToBuf(server.bInt),
}, { upsert: true, returnNewDocument: false }); }, { upsert: true, returnNewDocument: false });
@@ -115,32 +108,22 @@ export const login2 = async (req: Request, res: Response) => {
if (!req.headers['user-agent']) throw InternalServerError({ message: 'User-Agent header is required' }); if (!req.headers['user-agent']) throw InternalServerError({ message: 'User-Agent header is required' });
const { email, clientProof, providerAuthToken } = req.body; const { email, clientProof, providerAuthToken } = req.body;
let userId = '';
if (providerAuthToken) {
const decodedToken = <jwt.ProviderAuthJwtPayload>(
jwt.verify(providerAuthToken, await getJwtProviderAuthSecret())
);
userId = decodedToken.userId;
}
const filter = userId ? { const user = await User.findOne({
_id: userId,
} : {
email, email,
} }).select('+salt +verifier +encryptionVersion +protectedKey +protectedKeyIV +protectedKeyTag +publicKey +encryptedPrivateKey +iv +tag');
const user = await User.findOne(filter).select('+salt +verifier +encryptionVersion +protectedKey +protectedKeyIV +protectedKeyTag +publicKey +encryptedPrivateKey +iv +tag');
if (!user) throw new Error('Failed to find user'); if (!user) throw new Error('Failed to find user');
const identifier = userId ? { if (user.authProvider) {
userId, await validateProviderAuthToken({
} : { email,
email, user,
providerAuthToken,
})
} }
const loginSRPDetail = await LoginSRPDetail.findOneAndDelete({ ...identifier }); const loginSRPDetail = await LoginSRPDetail.findOneAndDelete({ userId: user.id });
if (!loginSRPDetail) { if (!loginSRPDetail) {
return BadRequestError(Error("Failed to find login details for SRP")) return BadRequestError(Error("Failed to find login details for SRP"))
+27
View File
@@ -20,6 +20,7 @@ import {
import { import {
getJwtAuthLifetime, getJwtAuthLifetime,
getJwtAuthSecret, getJwtAuthSecret,
getJwtProviderAuthSecret,
getJwtRefreshLifetime, getJwtRefreshLifetime,
getJwtRefreshSecret getJwtRefreshSecret
} from '../config'; } from '../config';
@@ -319,8 +320,34 @@ const createToken = ({
}); });
}; };
const validateProviderAuthToken = async ({
email,
user,
providerAuthToken,
}: {
email: string;
user: IUser,
providerAuthToken?: string;
}) => {
if (!providerAuthToken) {
throw new Error('Invalid authentication request.');
}
const decodedToken = <jwt.ProviderAuthJwtPayload>(
jwt.verify(providerAuthToken, await getJwtProviderAuthSecret())
);
if (
decodedToken.authProvider !== user.authProvider ||
decodedToken.email !== email
) {
throw new Error('Invalid authentication credentials.')
}
}
export { export {
validateAuthMode, validateAuthMode,
validateProviderAuthToken,
getAuthUserPayload, getAuthUserPayload,
getAuthSTDPayload, getAuthSTDPayload,
getAuthSAAKPayload, getAuthSAAKPayload,
+6
View File
@@ -37,6 +37,7 @@ import {
membership as v1MembershipRouter, membership as v1MembershipRouter,
key as v1KeyRouter, key as v1KeyRouter,
inviteOrg as v1InviteOrgRouter, inviteOrg as v1InviteOrgRouter,
oauth as v1OAuth,
user as v1UserRouter, user as v1UserRouter,
userAction as v1UserActionRouter, userAction as v1UserActionRouter,
secret as v1SecretRouter, secret as v1SecretRouter,
@@ -78,6 +79,7 @@ import {
getSiteURL, getSiteURL,
getSessionSecret, getSessionSecret,
} from './config'; } from './config';
import { initializePassport } from './utils/auth';
const main = async () => { const main = async () => {
TelemetryService.logTelemetryMessage(); TelemetryService.logTelemetryMessage();
@@ -95,6 +97,9 @@ const main = async () => {
patchRouterParam(); patchRouterParam();
const app = express(); const app = express();
await initializePassport();
app.enable('trust proxy'); app.enable('trust proxy');
app.use(express.json()); app.use(express.json());
app.use(cookieParser()); app.use(cookieParser());
@@ -129,6 +134,7 @@ const main = async () => {
// v1 routes (default) // v1 routes (default)
app.use('/api/v1/signup', v1SignupRouter); app.use('/api/v1/signup', v1SignupRouter);
app.use('/api/v1/auth', v1AuthRouter); app.use('/api/v1/auth', v1AuthRouter);
app.use('/api/v1/oauth', v1OAuth);
app.use('/api/v1/bot', v1BotRouter); app.use('/api/v1/bot', v1BotRouter);
app.use('/api/v1/user', v1UserRouter); app.use('/api/v1/user', v1UserRouter);
app.use('/api/v1/user-action', v1UserActionRouter); app.use('/api/v1/user-action', v1UserActionRouter);
+2 -1
View File
@@ -16,7 +16,7 @@ import ServiceAccountKey, { IServiceAccountKey } from './serviceAccountKey'; //
import ServiceAccountOrganizationPermission, { IServiceAccountOrganizationPermission } from './serviceAccountOrganizationPermission'; // new import ServiceAccountOrganizationPermission, { IServiceAccountOrganizationPermission } from './serviceAccountOrganizationPermission'; // new
import ServiceAccountWorkspacePermission, { IServiceAccountWorkspacePermission } from './serviceAccountWorkspacePermission'; // new import ServiceAccountWorkspacePermission, { IServiceAccountWorkspacePermission } from './serviceAccountWorkspacePermission'; // new
import TokenData, { ITokenData } from './tokenData'; import TokenData, { ITokenData } from './tokenData';
import User, { IUser } from './user'; import User,{ AuthProvider, IUser } from './user';
import UserAction, { IUserAction } from './userAction'; import UserAction, { IUserAction } from './userAction';
import Workspace, { IWorkspace } from './workspace'; import Workspace, { IWorkspace } from './workspace';
import ServiceTokenData, { IServiceTokenData } from './serviceTokenData'; import ServiceTokenData, { IServiceTokenData } from './serviceTokenData';
@@ -24,6 +24,7 @@ import APIKeyData, { IAPIKeyData } from './apiKeyData';
import LoginSRPDetail, { ILoginSRPDetail } from './loginSRPDetail'; import LoginSRPDetail, { ILoginSRPDetail } from './loginSRPDetail';
export { export {
AuthProvider,
BackupPrivateKey, BackupPrivateKey,
IBackupPrivateKey, IBackupPrivateKey,
Bot, Bot,
+6 -1
View File
@@ -1,9 +1,13 @@
import { Schema, model, Types, Document } from 'mongoose'; import { Schema, model, Types, Document } from 'mongoose';
export enum AuthProvider {
GOOGLE = 'google',
}
export interface IUser extends Document { export interface IUser extends Document {
_id: Types.ObjectId; _id: Types.ObjectId;
authId?: string; authId?: string;
authProvider?: string; authProvider?: AuthProvider;
email: string; email: string;
firstName?: string; firstName?: string;
lastName?: string; lastName?: string;
@@ -33,6 +37,7 @@ const userSchema = new Schema<IUser>(
}, },
authProvider: { authProvider: {
type: String, type: String,
enum: AuthProvider,
}, },
email: { email: {
type: String, type: String,
-53
View File
@@ -1,50 +1,10 @@
import express from 'express'; import express from 'express';
const router = express.Router(); const router = express.Router();
import { body } from 'express-validator'; import { body } from 'express-validator';
import passport from 'passport';
import { requireAuth, validateRequest } from '../../middleware'; import { requireAuth, validateRequest } from '../../middleware';
import { authController } from '../../controllers/v1'; import { authController } from '../../controllers/v1';
import { authLimiter } from '../../helpers/rateLimiter'; import { authLimiter } from '../../helpers/rateLimiter';
import { AUTH_MODE_JWT } from '../../variables'; import { AUTH_MODE_JWT } from '../../variables';
import { User } from '../../models';
import { createToken } from '../../helpers/auth';
import { getJwtProviderAuthLifetime, getJwtProviderAuthSecret } from '../../config';
// eslint-disable-next-line @typescript-eslint/no-var-requires
const GoogleStrategy = require('passport-google-oidc');
passport.use(new GoogleStrategy({
passReqToCallback: true,
clientID: process.env['GOOGLE_CLIENT_ID'],
clientSecret: process.env['GOOGLE_CLIENT_SECRET'],
callbackURL: '/api/v1/auth/google/callback',
}, async (req: express.Request, issuer: any, profile: any, cb: any) => {
const email = profile.emails[0].value;
let user = await User.findOne({
authProvider: issuer,
authId: profile.id,
})
if (!user) {
user = await new User({
email,
authProvider: issuer,
authId: profile.id,
}).save();
}
const providerAuthToken = createToken({
payload: {
userId: user._id.toString(),
email: user.email,
},
expiresIn: await getJwtProviderAuthLifetime(),
secret: await getJwtProviderAuthSecret(),
});
req.providerAuthToken = providerAuthToken;
cb(null, profile);
}));
router.post('/token', validateRequest, authController.getNewToken); router.post('/token', validateRequest, authController.getNewToken);
@@ -83,18 +43,5 @@ router.post(
authController.checkAuth authController.checkAuth
); );
router.get(
'/login/google',
authLimiter,
passport.authenticate('google', {
scope: ['profile', 'email'],
}),
)
router.get(
'/google/callback',
passport.authenticate('google', { failureRedirect: '/error', session: false }),
authController.handleGoogleCallback,
)
export default router; export default router;
+3 -1
View File
@@ -15,7 +15,8 @@ import password from './password';
import stripe from './stripe'; import stripe from './stripe';
import integration from './integration'; import integration from './integration';
import integrationAuth from './integrationAuth'; import integrationAuth from './integrationAuth';
import secretsFolder from './secretsFolder' import secretsFolder from './secretsFolder';
import oauth from './oauth';
export { export {
signup, signup,
@@ -29,6 +30,7 @@ export {
membership, membership,
key, key,
inviteOrg, inviteOrg,
oauth,
secret, secret,
serviceToken, serviceToken,
password, password,
+21
View File
@@ -0,0 +1,21 @@
import express from 'express';
const router = express.Router();
import passport from 'passport';
import { oauthController } from '../../controllers/v1';
import { authLimiter } from '../../helpers/rateLimiter';
router.get(
'/redirect/google',
authLimiter,
passport.authenticate('google', {
scope: ['profile', 'email'],
}),
)
router.get(
'/callback/google',
passport.authenticate('google', { failureRedirect: '/error', session: false }),
oauthController.handleAuthProviderCallback,
)
export default router;
+55 -3
View File
@@ -1,10 +1,22 @@
import express from 'express';
import passport from 'passport';
import { AuthData } from '../interfaces/middleware'; import { AuthData } from '../interfaces/middleware';
import { import {
AuthProvider,
User, User,
ServiceAccount, ServiceAccount,
ServiceTokenData, ServiceTokenData,
ServiceToken
} from '../models'; } from '../models';
import { createToken } from '../helpers/auth';
import {
getClientIdGoogle,
getClientSecretGoogle,
getJwtProviderAuthLifetime,
getJwtProviderAuthSecret
} from '../config';
// eslint-disable-next-line @typescript-eslint/no-var-requires
const GoogleStrategy = require('passport-google-oidc');
// TODO: find a more optimal folder structure to store these types of functions // TODO: find a more optimal folder structure to store these types of functions
@@ -48,7 +60,47 @@ const getAuthDataPayloadUserObj = (authData: AuthData) => {
} }
} }
const initializePassport = async () => {
const googleClientSecret = await getClientSecretGoogle();
const googleClientId = await getClientIdGoogle();
passport.use(new GoogleStrategy({
passReqToCallback: true,
clientID: googleClientId,
clientSecret: googleClientSecret,
callbackURL: '/api/v1/oauth/callback/google',
}, async (req: express.Request, issuer: any, profile: any, cb: any) => {
const email = profile.emails[0].value;
let user = await User.findOne({
authProvider: AuthProvider.GOOGLE,
authId: profile.id,
})
if (!user) {
user = await new User({
email,
authProvider: AuthProvider.GOOGLE,
authId: profile.id,
}).save();
}
const providerAuthToken = createToken({
payload: {
userId: user._id.toString(),
email: user.email,
authProvider: user.authProvider,
},
expiresIn: await getJwtProviderAuthLifetime(),
secret: await getJwtProviderAuthSecret(),
});
req.providerAuthToken = providerAuthToken;
cb(null, profile);
}));
}
export { export {
getAuthDataPayloadIdObj, getAuthDataPayloadIdObj,
getAuthDataPayloadUserObj getAuthDataPayloadUserObj,
} initializePassport,
}
+8 -8
View File
@@ -24,12 +24,12 @@ export default function Login() {
const lang = router.locale ?? 'en'; const lang = router.locale ?? 'en';
const [isLoginWithEmail, setIsLoginWithEmail] = useState(false); const [isLoginWithEmail, setIsLoginWithEmail] = useState(false);
const { const {
providerAuthToken, providerAuthToken,
userId, userId,
email: providerEmail, email: providerEmail,
setProviderAuthToken setProviderAuthToken
} = useProviderAuth(); } = useProviderAuth();
const setLanguage = async (to: string) => { const setLanguage = async (to: string) => {
router.push('/login', '/login', { locale: to }); router.push('/login', '/login', { locale: to });
localStorage.setItem('lang', to); localStorage.setItem('lang', to);
@@ -51,7 +51,7 @@ export default function Login() {
redirectToDashboard(); redirectToDashboard();
} }
}, []); }, []);
const renderView = (loginStep: number) => { const renderView = (loginStep: number) => {
if (providerAuthToken && step === 1) { if (providerAuthToken && step === 1) {
@@ -83,12 +83,12 @@ export default function Login() {
return ( return (
<> <>
<button type='button' className='text-white' onClick={() => { <button type='button' className='text-white' onClick={() => {
window.open('/api/v1/auth/login/google') window.open('/api/v1/oauth/redirect/google')
}}> }}>
Continue with Google Continue with Google
</button> </button>
<button type='button' className='text-white' onClick={() => { <button type='button' className='text-white' onClick={() => {
setIsLoginWithEmail(true); setIsLoginWithEmail(true);
}}> }}>
Continue with Email Continue with Email
</button> </button>
+79 -32
View File
@@ -14,10 +14,12 @@ import UserInfoStep from '@app/components/signup/UserInfoStep';
import SecurityClient from '@app/components/utilities/SecurityClient'; import SecurityClient from '@app/components/utilities/SecurityClient';
import { getTranslatedStaticProps } from '@app/components/utilities/withTranslateProps'; import { getTranslatedStaticProps } from '@app/components/utilities/withTranslateProps';
import { useFetchServerStatus } from '@app/hooks/api/serverDetails'; import { useFetchServerStatus } from '@app/hooks/api/serverDetails';
import { useProviderAuth } from '@app/hooks/useProviderAuth';
import checkEmailVerificationCode from './api/auth/CheckEmailVerificationCode'; import checkEmailVerificationCode from './api/auth/CheckEmailVerificationCode';
import getWorkspaces from './api/workspace/getWorkspaces'; import getWorkspaces from './api/workspace/getWorkspaces';
/** /**
* @returns the signup page * @returns the signup page
*/ */
@@ -31,7 +33,13 @@ export default function SignUp() {
const [step, setStep] = useState(1); const [step, setStep] = useState(1);
const router = useRouter(); const router = useRouter();
const { data: serverDetails } = useFetchServerStatus(); const { data: serverDetails } = useFetchServerStatus();
const [isSignupWithEmail, setIsSignupWithEmail] = useState(false);
const { t } = useTranslation(); const { t } = useTranslation();
const { providerAuthToken } = useProviderAuth();
if (providerAuthToken && step < 3) {
setStep(3);
}
useEffect(() => { useEffect(() => {
const tryAuth = async () => { const tryAuth = async () => {
@@ -60,7 +68,7 @@ export default function SignUp() {
// Checking if the code matches the email. // Checking if the code matches the email.
const response = await checkEmailVerificationCode({ email, code }); const response = await checkEmailVerificationCode({ email, code });
if (response.status === 200) { if (response.status === 200) {
const {token} = await response.json(); const { token } = await response.json();
SecurityClient.setSignupToken(token); SecurityClient.setSignupToken(token);
setStep(3); setStep(3);
} else { } else {
@@ -71,17 +79,83 @@ export default function SignUp() {
// when email service is not configured, skip step 2 and 5 // when email service is not configured, skip step 2 and 5
useEffect(() => { useEffect(() => {
if (!serverDetails?.emailConfigured && step === 2){ if (!serverDetails?.emailConfigured && step === 2) {
incrementStep() incrementStep()
} }
if (!serverDetails?.emailConfigured && step === 5){ if (!serverDetails?.emailConfigured && step === 5) {
getWorkspaces().then((userWorkspaces)=>{ getWorkspaces().then((userWorkspaces) => {
router.push(`/dashboard/${userWorkspaces[0]._id}`); router.push(`/dashboard/${userWorkspaces[0]._id}`);
}); });
} }
}, [step]); }, [step]);
const renderView = (registerStep: number) => {
if (isSignupWithEmail && registerStep === 1) {
return <EnterEmailStep email={email} setEmail={setEmail} incrementStep={incrementStep} />
}
if (!isSignupWithEmail && registerStep === 1) {
return (
<>
<button type='button' className='text-white' onClick={() => {
window.open('/api/v1/auth/login/google')
}}>
Continue with Google
</button>
<button type='button' className='text-white' onClick={() => {
setIsSignupWithEmail(true);
}}>
Continue with Email
</button>
</>
)
}
if (registerStep === 2) {
return (
<CodeInputStep
email={email}
incrementStep={incrementStep}
setCode={setCode}
codeError={codeError}
/>
)
}
if (registerStep === 3) {
return (
<UserInfoStep
incrementStep={incrementStep}
email={email}
password={password}
setPassword={setPassword}
firstName={firstName}
setFirstName={setFirstName}
lastName={lastName}
setLastName={setLastName}
/>
)
}
if (registerStep === 4) {
return (
<DownloadBackupPDF
incrementStep={incrementStep}
email={email}
password={password}
name={`${firstName} ${lastName}`}
/>
)
}
if (serverDetails?.emailConfigured) {
return <TeamInviteStep />
}
return ""
}
return ( return (
<div className="bg-bunker-800 h-screen flex flex-col items-center justify-center"> <div className="bg-bunker-800 h-screen flex flex-col items-center justify-center">
<Head> <Head>
@@ -98,34 +172,7 @@ export default function SignUp() {
</div> </div>
</Link> </Link>
<form onSubmit={(e) => e.preventDefault()}> <form onSubmit={(e) => e.preventDefault()}>
{step === 1 ? ( {renderView(step)}
<EnterEmailStep email={email} setEmail={setEmail} incrementStep={incrementStep} />
) : step === 2 ? (
<CodeInputStep
email={email}
incrementStep={incrementStep}
setCode={setCode}
codeError={codeError}
/>
) : step === 3 ? (
<UserInfoStep
incrementStep={incrementStep}
email={email}
password={password}
setPassword={setPassword}
firstName={firstName}
setFirstName={setFirstName}
lastName={lastName}
setLastName={setLastName}
/>
) : step === 4 ? (
<DownloadBackupPDF
incrementStep={incrementStep}
email={email}
password={password}
name={`${firstName} ${lastName}`}
/>
) : (serverDetails?.emailConfigured ? <TeamInviteStep /> : "")}
</form> </form>
</div> </div>
</div> </div>