Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,10 @@ PLAID_COUNTRY_CODES=
PLAID_INTERVAL_IN_DAYS=


# Automatically redirect sign-in when exactly one OAuth provider is configured and no other
# authentication providers are enabled
OAUTH_AUTO_REDIRECT=false

# Google Provider : https://next-auth.js.org/providers/google
GOOGLE_CLIENT_ID=
GOOGLE_CLIENT_SECRET=
Expand Down
4 changes: 4 additions & 0 deletions docs/CONFIGURATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,10 @@ Used for magic-link login and invites.

### OAuth providers

#### Shared OAuth settings

- `OAUTH_AUTO_REDIRECT`: Optional flag. When set to `true`, the sign-in page automatically redirects when exactly one OAuth provider is configured and no other authentication providers are enabled. This applies to Google, Authentik, Keycloak, and generic OIDC.

#### Google

- `GOOGLE_CLIENT_ID`
Expand Down
2 changes: 2 additions & 0 deletions src/env.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ export const env = createEnv({
OIDC_CLIENT_SECRET: z.string().optional(),
OIDC_WELL_KNOWN_URL: z.string().optional(),
OIDC_ALLOW_DANGEROUS_EMAIL_LINKING: z.boolean().default(false),
OAUTH_AUTO_REDIRECT: z.boolean().default(false),
UPLOAD_MAX_FILE_SIZE_MB: z.coerce.number().int().positive().default(10),
},

Expand Down Expand Up @@ -142,6 +143,7 @@ export const env = createEnv({
OIDC_ALLOW_DANGEROUS_EMAIL_LINKING: Boolean(
JSON.parse(process.env.OIDC_ALLOW_DANGEROUS_EMAIL_LINKING || 'false'),
),
OAUTH_AUTO_REDIRECT: Boolean(JSON.parse(process.env.OAUTH_AUTO_REDIRECT || 'false')),
UPLOAD_MAX_FILE_SIZE_MB: process.env.UPLOAD_MAX_FILE_SIZE_MB
? Number(process.env.UPLOAD_MAX_FILE_SIZE_MB)
: 10,
Expand Down
27 changes: 26 additions & 1 deletion src/pages/auth/signin.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,8 @@ const Home: NextPage<{
feedbackEmail: string;
providers: ClientSafeProvider[];
callbackUrl?: string;
}> = ({ error, providers: serverProviders, feedbackEmail, callbackUrl }) => {
oauthAutoRedirect: boolean;
}> = ({ error, providers: serverProviders, feedbackEmail, callbackUrl, oauthAutoRedirect }) => {
const { t } = useTranslation();
const [emailStatus, setEmailStatus] = useState<'idle' | 'sending' | 'success'>('idle');
const [showVerificationStep, setShowVerificationStep] = useState(false);
Expand Down Expand Up @@ -110,6 +111,29 @@ const Home: NextPage<{
}
}, [error, t]);

useEffect(() => {
const oauthProviders = providers.filter((provider) => 'oauth' === provider.type);
// SessionRequired indicates an unauthenticated route redirect, not a failed sign-in.
const hasSignInError = Boolean(error && 'SessionRequired' !== error);
const shouldAutoRedirect =
oauthAutoRedirect && !hasSignInError && 1 === oauthProviders.length && 1 === providers.length;

const oauthProvider = oauthProviders[0];
if (shouldAutoRedirect && oauthProvider && !showVerificationStep && !isLoadingProviders) {
void signIn(oauthProvider.id, { callbackUrl }).catch(() => {
toast.error(t('errors.signin_error'));
});
}
}, [
oauthAutoRedirect,
error,
showVerificationStep,
providers,
isLoadingProviders,
callbackUrl,
t,
]);

Comment thread
coderabbitai[bot] marked this conversation as resolved.
const onEmailSubmit = useCallback(async () => {
setEmailStatus('sending');
const email = emailForm.getValues().email.toLowerCase();
Expand Down Expand Up @@ -293,6 +317,7 @@ export const getServerSideProps: GetServerSideProps = async (context) => {
feedbackEmail: env.FEEDBACK_EMAIL ?? '',
providers: Object.values(providers ?? {}),
callbackUrl: callbackUrl && !Array.isArray(callbackUrl) ? callbackUrl : '',
oauthAutoRedirect: env.OAUTH_AUTO_REDIRECT,
},
};
};
8 changes: 8 additions & 0 deletions src/server/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,14 @@ export function validateAuthEnv() {
console.log('Validating auth env');
if (!process.env.SKIP_ENV_VALIDATION) {
const providers = getProviders();
const oauthProviders = providers.filter((provider) => 'oauth' === provider.type);

if (env.OAUTH_AUTO_REDIRECT && (1 !== oauthProviders.length || 1 !== providers.length)) {
console.warn(
'OAUTH_AUTO_REDIRECT is enabled, but automatic redirection will not happen until exactly one OAuth provider and no other authentication providers are configured.',
);
}

if (0 === providers.length) {
throw new Error(
'No authentication providers are configured, at least one is required. Learn more here: https://github.com/oss-apps/split-pro?tab=readme-ov-file#setting-up-the-environment',
Expand Down
Loading