diff --git a/app/auth/sign-up/page.tsx b/app/auth/sign-up/page.tsx index 52d77e9..cdee3a5 100644 --- a/app/auth/sign-up/page.tsx +++ b/app/auth/sign-up/page.tsx @@ -57,10 +57,9 @@ async function SignUpPage({ searchParams }: Props) {
diff --git a/app/auth/update-account/_components/update-account-form.tsx b/app/auth/update-account/_components/update-account-form.tsx index a657755..b807745 100644 --- a/app/auth/update-account/_components/update-account-form.tsx +++ b/app/auth/update-account/_components/update-account-form.tsx @@ -59,10 +59,10 @@ export function UpdateAccountForm({ const loading = toast.loading(t('updateAccount.updateAccountLoading')); try { const response = await onUpdateAccount({ - firstName: hasFirstName ? firstName : values.firstName, - lastName: hasLastName ? lastName : values.lastName, - personalCode: hasPersonalCode ? personalCode : values.personalCode, - email: hasEmail ? email : values.email, + firstName: values.firstName || firstName, + lastName: values.lastName || lastName, + personalCode: values.personalCode || personalCode, + email: values.email || email, phone: values.phone, weight: ((("weight" in values && values.weight) ?? defaultValues_weight) || null) as number, height: ((("height" in values && values.height) ?? defaultValues_height) || null) as number, diff --git a/packages/features/auth/src/components/auth-layout.tsx b/packages/features/auth/src/components/auth-layout.tsx index 2d83e61..003da16 100644 --- a/packages/features/auth/src/components/auth-layout.tsx +++ b/packages/features/auth/src/components/auth-layout.tsx @@ -7,9 +7,8 @@ export function AuthLayoutShell({ return (
{Logo ? : null} diff --git a/packages/features/auth/src/components/oauth-providers.tsx b/packages/features/auth/src/components/oauth-providers.tsx index 11dcc94..2bb7830 100644 --- a/packages/features/auth/src/components/oauth-providers.tsx +++ b/packages/features/auth/src/components/oauth-providers.tsx @@ -113,12 +113,16 @@ export const OauthProviders: React.FC<{ ); }} > - + {provider === 'keycloak' ? ( + + ) : ( + + )} ); })} diff --git a/packages/features/auth/src/components/password-sign-up-container.tsx b/packages/features/auth/src/components/password-sign-up-container.tsx index 5cbe21a..631c7a5 100644 --- a/packages/features/auth/src/components/password-sign-up-container.tsx +++ b/packages/features/auth/src/components/password-sign-up-container.tsx @@ -10,9 +10,18 @@ import { useCaptchaToken } from '../captcha/client'; import { usePasswordSignUpFlow } from '../hooks/use-sign-up-flow'; import { AuthErrorAlert } from './auth-error-alert'; import { PasswordSignUpForm } from './password-sign-up-form'; +import { Spinner } from '@kit/ui/makerkit/spinner'; interface EmailPasswordSignUpContainerProps { - displayTermsCheckbox?: boolean; + authConfig: { + providers: { + password: boolean; + magicLink: boolean; + oAuth: string[]; + }; + displayTermsCheckbox: boolean | undefined; + isMailerAutoconfirmEnabled: boolean; + }; defaultValues?: { email: string; }; @@ -21,10 +30,10 @@ interface EmailPasswordSignUpContainerProps { } export function EmailPasswordSignUpContainer({ + authConfig, defaultValues, onSignUp, emailRedirectTo, - displayTermsCheckbox, }: EmailPasswordSignUpContainerProps) { const { captchaToken, resetCaptchaToken } = useCaptchaToken(); @@ -43,7 +52,12 @@ export function EmailPasswordSignUpContainer({ return ( <> - + {authConfig.isMailerAutoconfirmEnabled ? ( +
+ +
+ ) : + }
@@ -53,7 +67,7 @@ export function EmailPasswordSignUpContainer({ onSubmit={onSignupRequested} loading={loading} defaultValues={defaultValues} - displayTermsCheckbox={displayTermsCheckbox} + displayTermsCheckbox={authConfig.displayTermsCheckbox} /> diff --git a/packages/features/auth/src/components/sign-up-methods-container.tsx b/packages/features/auth/src/components/sign-up-methods-container.tsx index 8759e0c..00782bd 100644 --- a/packages/features/auth/src/components/sign-up-methods-container.tsx +++ b/packages/features/auth/src/components/sign-up-methods-container.tsx @@ -1,6 +1,7 @@ 'use client'; import type { Provider } from '@supabase/supabase-js'; +import { useRouter } from 'next/navigation'; import { isBrowser } from '@kit/shared/utils'; import { Alert, AlertDescription, AlertTitle } from '@kit/ui/alert'; @@ -19,15 +20,20 @@ export function SignUpMethodsContainer(props: { updateAccount: string; }; - providers: { - password: boolean; - magicLink: boolean; - oAuth: Provider[]; + authConfig: { + providers: { + password: boolean; + magicLink: boolean; + oAuth: Provider[]; + }; + displayTermsCheckbox: boolean | undefined; + isMailerAutoconfirmEnabled: boolean; }; - displayTermsCheckbox?: boolean; inviteToken?: string; }) { + const router = useRouter(); + const redirectUrl = getCallbackUrl(props); const defaultValues = getDefaultValues(); @@ -37,26 +43,33 @@ export function SignUpMethodsContainer(props: { - + redirect(redirectUrl)} + authConfig={props.authConfig} + onSignUp={() => { + if (!props.authConfig.isMailerAutoconfirmEnabled) { + return; + } + setTimeout(() => { + router.replace(props.paths.updateAccount) + }, 2_500); + }} /> - + - +
@@ -70,7 +83,7 @@ export function SignUpMethodsContainer(props: {
{icon || } - {content} + {content} ); diff --git a/packages/shared/src/config/auth-providers.service.ts b/packages/shared/src/config/auth-providers.service.ts index 5cdb599..179e7da 100644 --- a/packages/shared/src/config/auth-providers.service.ts +++ b/packages/shared/src/config/auth-providers.service.ts @@ -5,6 +5,7 @@ type SupabaseExternalProvider = Provider | 'email'; interface SupabaseAuthSettings { external: Record; disable_signup: boolean; + mailer_autoconfirm: boolean; } export class AuthProvidersService { @@ -61,6 +62,10 @@ export class AuthProvidersService { return process.env.NEXT_PUBLIC_AUTH_PASSWORD === 'true'; } + isMailerAutoconfirmEnabled({ settings }: { settings: SupabaseAuthSettings | null }): boolean { + return settings?.mailer_autoconfirm === true; + } + isMagicLinkEnabled(): boolean { return process.env.NEXT_PUBLIC_AUTH_MAGIC_LINK === 'true'; } @@ -105,10 +110,11 @@ export class AuthProvidersService { async getAuthConfig() { const settings = await this.fetchAuthSettings(); - const [passwordEnabled, magicLinkEnabled, oAuthProviders] = await Promise.all([ + const [passwordEnabled, magicLinkEnabled, oAuthProviders, isMailerAutoconfirmEnabled] = await Promise.all([ this.isPasswordEnabled({ settings }), this.isMagicLinkEnabled(), this.getEnabledOAuthProviders({ settings }), + this.isMailerAutoconfirmEnabled({ settings }), ]); return { @@ -118,6 +124,7 @@ export class AuthProvidersService { oAuth: oAuthProviders, }, displayTermsCheckbox: authConfig.displayTermsCheckbox, + isMailerAutoconfirmEnabled, }; } diff --git a/packages/shared/src/config/dynamic-auth.config.ts b/packages/shared/src/config/dynamic-auth.config.ts index 428be33..571516a 100644 --- a/packages/shared/src/config/dynamic-auth.config.ts +++ b/packages/shared/src/config/dynamic-auth.config.ts @@ -11,8 +11,19 @@ const DynamicAuthConfigSchema = z.object({ oAuth: providers.array(), }), displayTermsCheckbox: z.boolean().describe('Whether to display the terms checkbox during sign-up.'), + isMailerAutoconfirmEnabled: z.boolean().describe('Whether Supabase sends confirmation email automatically.'), }); +export type DynamicAuthConfig = { + providers: { + password: boolean; + magicLink: boolean; + oAuth: Provider[]; + }; + displayTermsCheckbox: boolean | undefined; + isMailerAutoconfirmEnabled: boolean; +} + export async function getDynamicAuthConfig() { const authService = createAuthProvidersService(); const dynamicProviders = await authService.getAuthConfig(); @@ -20,6 +31,7 @@ export async function getDynamicAuthConfig() { const config = { providers: dynamicProviders.providers, displayTermsCheckbox: dynamicProviders.displayTermsCheckbox, + isMailerAutoconfirmEnabled: dynamicProviders.isMailerAutoconfirmEnabled, }; return DynamicAuthConfigSchema.parse(config); diff --git a/packages/shared/src/config/index.ts b/packages/shared/src/config/index.ts index 5669259..d1737bb 100644 --- a/packages/shared/src/config/index.ts +++ b/packages/shared/src/config/index.ts @@ -8,7 +8,7 @@ import { createPath, getTeamAccountSidebarConfig, } from './team-account-navigation.config'; -import { getCachedAuthConfig, getServerAuthConfig } from './dynamic-auth.config'; +import { DynamicAuthConfig, getCachedAuthConfig, getServerAuthConfig } from './dynamic-auth.config'; export { appConfig, @@ -21,4 +21,5 @@ export { personalAccountNavigationConfig, getCachedAuthConfig, getServerAuthConfig, + type DynamicAuthConfig, }; diff --git a/packages/ui/src/makerkit/page.tsx b/packages/ui/src/makerkit/page.tsx index 6ca7573..b4ee923 100644 --- a/packages/ui/src/makerkit/page.tsx +++ b/packages/ui/src/makerkit/page.tsx @@ -42,7 +42,7 @@ function PageWithSidebar(props: PageProps) { > {MobileNavigation} -
+
{Children}
diff --git a/packages/ui/src/shadcn/card.tsx b/packages/ui/src/shadcn/card.tsx index fec5a6b..9841c3e 100644 --- a/packages/ui/src/shadcn/card.tsx +++ b/packages/ui/src/shadcn/card.tsx @@ -34,7 +34,7 @@ const CardHeader: React.FC> = ({ className, ...props }) => ( -
+
); CardHeader.displayName = 'CardHeader'; @@ -60,14 +60,14 @@ CardDescription.displayName = 'CardDescription'; const CardContent: React.FC> = ({ className, ...props -}) =>
; +}) =>
; CardContent.displayName = 'CardContent'; const CardFooter: React.FC> = ({ className, ...props }) => ( -
+
); CardFooter.displayName = 'CardFooter'; diff --git a/public/locales/en/auth.json b/public/locales/en/auth.json index 7db0925..5c89064 100644 --- a/public/locales/en/auth.json +++ b/public/locales/en/auth.json @@ -22,6 +22,7 @@ "alreadyHaveAccountStatement": "I already have an account, I want to sign in instead", "doNotHaveAccountStatement": "I do not have an account, I want to sign up instead", "signInWithProvider": "Sign in with {{provider}}", + "signInWithKeycloak": "Smart-ID/Mobile-ID/ID-card", "signInWithPhoneNumber": "Sign in with Phone Number", "signInWithEmail": "Sign in with Email", "signUpWithEmail": "Sign up with Email", diff --git a/public/locales/et/auth.json b/public/locales/et/auth.json index d9ebf9b..4919b25 100644 --- a/public/locales/et/auth.json +++ b/public/locales/et/auth.json @@ -2,7 +2,7 @@ "signUpHeading": "Loo konto", "signUp": "Loo konto", "signUpSubheading": "Täida allolev vorm, et luua konto.", - "signInHeading": "Logi oma kontole sisse", + "signInHeading": "Logi sisse", "signInSubheading": "Tere tulemast tagasi! Palun sisesta oma andmed", "signIn": "Logi sisse", "getStarted": "Alusta", @@ -22,6 +22,7 @@ "alreadyHaveAccountStatement": "Mul on juba konto, ma tahan sisse logida", "doNotHaveAccountStatement": "Mul pole kontot, ma tahan registreeruda", "signInWithProvider": "Logi sisse teenusega {{provider}}", + "signInWithKeycloak": "Smart-ID/Mobiil-ID/ID-kaart", "signInWithPhoneNumber": "Logi sisse telefoninumbriga", "signInWithEmail": "Logi sisse e-posti aadressiga", "signUpWithEmail": "Registreeru e-posti aadressiga", @@ -68,7 +69,7 @@ "acceptTermsAndConditions": "Ma nõustun ja ", "termsOfService": "Kasutustingimused", "privacyPolicy": "Privaatsuspoliitika", - "orContinueWith": "Või jätka koos", + "orContinueWith": "Või", "redirecting": "Oled sees! Palun oota...", "errors": { "Invalid login credentials": "Sisestatud andmed on valed", diff --git a/public/locales/ru/auth.json b/public/locales/ru/auth.json index 8634403..5dc5e1d 100644 --- a/public/locales/ru/auth.json +++ b/public/locales/ru/auth.json @@ -22,6 +22,7 @@ "alreadyHaveAccountStatement": "У меня уже есть аккаунт, я хочу войти", "doNotHaveAccountStatement": "У меня нет аккаунта, я хочу зарегистрироваться", "signInWithProvider": "Войти через {{provider}}", + "signInWithKeycloak": "Smart-ID/Mobiil-ID/ID-kaart", "signInWithPhoneNumber": "Войти по номеру телефона", "signInWithEmail": "Войти по Email", "signUpWithEmail": "Зарегистрироваться по Email",