Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 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
12 changes: 10 additions & 2 deletions apps/sim/app/(auth)/components/oauth-provider-checker.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
import { env } from '@/lib/core/config/env'
import { isGithubAuthDisabled, isGoogleAuthDisabled, isProd } from '@/lib/core/config/feature-flags'
import {
isGithubAuthDisabled,
isGoogleAuthDisabled,
isMicrosoftAuthDisabled,
isProd,
} from '@/lib/core/config/feature-flags'

export async function getOAuthProviderStatus() {
const githubAvailable =
Expand All @@ -8,5 +13,8 @@ export async function getOAuthProviderStatus() {
const googleAvailable =
!!(env.GOOGLE_CLIENT_ID && env.GOOGLE_CLIENT_SECRET) && !isGoogleAuthDisabled

return { githubAvailable, googleAvailable, isProduction: isProd }
const microsoftAvailable =
!!(env.MICROSOFT_CLIENT_ID && env.MICROSOFT_CLIENT_SECRET) && !isMicrosoftAuthDisabled

return { githubAvailable, googleAvailable, microsoftAvailable, isProduction: isProd }
}
43 changes: 41 additions & 2 deletions apps/sim/app/(auth)/components/social-login-buttons.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@

import { type ReactNode, useState } from 'react'
import { Button } from '@/components/emcn'
import { GithubIcon, GoogleIcon } from '@/components/icons'
import { GithubIcon, GoogleIcon, MicrosoftIcon } from '@/components/icons'
import { client } from '@/lib/auth/auth-client'

interface SocialLoginButtonsProps {
githubAvailable: boolean
googleAvailable: boolean
microsoftAvailable: boolean
callbackURL?: string
isProduction: boolean
children?: ReactNode
Expand All @@ -16,12 +17,14 @@ interface SocialLoginButtonsProps {
export function SocialLoginButtons({
githubAvailable,
googleAvailable,
microsoftAvailable,
callbackURL = '/workspace',
isProduction,
children,
}: SocialLoginButtonsProps) {
const [isGithubLoading, setIsGithubLoading] = useState(false)
const [isGoogleLoading, setIsGoogleLoading] = useState(false)
const [isMicrosoftLoading, setIsMicrosoftLoading] = useState(false)

async function signInWithGithub() {
if (!githubAvailable) return
Expand Down Expand Up @@ -69,6 +72,29 @@ export function SocialLoginButtons({
}
}

async function signInWithMicrosoft() {
if (!microsoftAvailable) return

setIsMicrosoftLoading(true)
try {
await client.signIn.social({ provider: 'microsoft', callbackURL })
} catch (err: any) {
let errorMessage = 'Failed to sign in with Microsoft'

if (err.message?.includes('account exists')) {
errorMessage = 'An account with this email already exists. Please sign in instead.'
} else if (err.message?.includes('cancelled')) {
errorMessage = 'Microsoft sign in was cancelled. Please try again.'
} else if (err.message?.includes('network')) {
errorMessage = 'Network error. Please check your connection and try again.'
} else if (err.message?.includes('rate limit')) {
errorMessage = 'Too many attempts. Please try again later.'
}
} finally {
setIsMicrosoftLoading(false)
}
}
Comment thread
TheodoreSpeaks marked this conversation as resolved.

const githubButton = (
<Button
variant='outline'
Expand All @@ -93,7 +119,19 @@ export function SocialLoginButtons({
</Button>
)

const hasAnyOAuthProvider = githubAvailable || googleAvailable
const microsoftButton = (
<Button
variant='outline'
className='w-full rounded-sm border-[var(--landing-border-strong)] py-1.5 text-sm'
disabled={!microsoftAvailable || isMicrosoftLoading}
onClick={signInWithMicrosoft}
>
<MicrosoftIcon className='!h-[18px] !w-[18px] mr-1' />
{isMicrosoftLoading ? 'Connecting...' : 'Microsoft'}
</Button>
)

const hasAnyOAuthProvider = githubAvailable || googleAvailable || microsoftAvailable

if (!hasAnyOAuthProvider && !children) {
return null
Expand All @@ -102,6 +140,7 @@ export function SocialLoginButtons({
return (
<div className='grid gap-3 font-light'>
{googleAvailable && googleButton}
{microsoftAvailable && microsoftButton}
{githubAvailable && githubButton}
{children}
</div>
Expand Down
5 changes: 4 additions & 1 deletion apps/sim/app/(auth)/login/login-form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -78,10 +78,12 @@ const validatePassword = (passwordValue: string): string[] => {
export default function LoginPage({
githubAvailable,
googleAvailable,
microsoftAvailable,
isProduction,
}: {
githubAvailable: boolean
googleAvailable: boolean
microsoftAvailable: boolean
isProduction: boolean
}) {
const router = useRouter()
Expand Down Expand Up @@ -335,7 +337,7 @@ export default function LoginPage({

const ssoEnabled = isTruthy(getEnv('NEXT_PUBLIC_SSO_ENABLED'))
const emailEnabled = !isFalsy(getEnv('NEXT_PUBLIC_EMAIL_PASSWORD_SIGNUP_ENABLED'))
const hasSocial = githubAvailable || googleAvailable
const hasSocial = githubAvailable || googleAvailable || microsoftAvailable
const hasOnlySSO = ssoEnabled && !emailEnabled && !hasSocial
const showTopSSO = hasOnlySSO
const showBottomSection = hasSocial || (ssoEnabled && !hasOnlySSO)
Expand Down Expand Up @@ -483,6 +485,7 @@ export default function LoginPage({
<div className={cn(!emailEnabled ? 'mt-8' : undefined)}>
<SocialLoginButtons
googleAvailable={googleAvailable}
microsoftAvailable={microsoftAvailable}
githubAvailable={githubAvailable}
isProduction={isProduction}
callbackURL={callbackUrl}
Expand Down
4 changes: 3 additions & 1 deletion apps/sim/app/(auth)/login/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,15 @@ export const metadata: Metadata = {
export const dynamic = 'force-dynamic'

export default async function LoginPage() {
const { githubAvailable, googleAvailable, isProduction } = await getOAuthProviderStatus()
const { githubAvailable, googleAvailable, microsoftAvailable, isProduction } =
await getOAuthProviderStatus()

return (
<Suspense fallback={null}>
<LoginForm
githubAvailable={githubAvailable}
googleAvailable={googleAvailable}
microsoftAvailable={microsoftAvailable}
isProduction={isProduction}
/>
</Suspense>
Expand Down
4 changes: 3 additions & 1 deletion apps/sim/app/(auth)/signup/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,14 @@ export default async function SignupPage() {
return <div>Registration is disabled, please contact your admin.</div>
}

const { githubAvailable, googleAvailable, isProduction } = await getOAuthProviderStatus()
const { githubAvailable, googleAvailable, microsoftAvailable, isProduction } =
await getOAuthProviderStatus()

return (
<SignupForm
githubAvailable={githubAvailable}
googleAvailable={googleAvailable}
microsoftAvailable={microsoftAvailable}
isProduction={isProduction}
/>
)
Expand Down
Loading
Loading