mirror of
https://github.com/supabase/supabase.git
synced 2026-10-06 18:05:11 +03:00
6 files changed
+45
-72
No files matched your search
@@ -11,11 +11,11 @@ const PasswordConditionsHelper = ({ password }: PasswordConditionsHelperProps) =
|
||||
|
||||
return (
|
||||
<div className="text-sm">
|
||||
<PasswordCondition title="One or more uppercase letters" isMet={hasUppercase} />
|
||||
<PasswordCondition title="One or more lowercase letters" isMet={hasLowercase} />
|
||||
<PasswordCondition title="One or more numbers" isMet={hasNumber} />
|
||||
<PasswordCondition title="One or more special characters" isMet={hasSpecialCharacter} />
|
||||
<PasswordCondition title="At least 8 characters long" isMet={isEightCharactersLong} />
|
||||
<PasswordCondition title="Uppercase letter" isMet={hasUppercase} />
|
||||
<PasswordCondition title="Lowercase letter" isMet={hasLowercase} />
|
||||
<PasswordCondition title="Number" isMet={hasNumber} />
|
||||
<PasswordCondition title="Special character (e.g. !?<>@#$%)" isMet={hasSpecialCharacter} />
|
||||
<PasswordCondition title="> 7 characters" isMet={isEightCharactersLong} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -31,7 +31,7 @@ const PasswordCondition = ({ title, isMet }: PasswordConditionProps) => {
|
||||
return (
|
||||
<div
|
||||
className={
|
||||
'flex items-center gap-1 transition duration-200 ' +
|
||||
'flex items-center gap-1 space-x-1.5 transition duration-200 ' +
|
||||
(isMet ? 'text-scale-1100' : 'text-scale-900')
|
||||
}
|
||||
>
|
||||
|
||||
@@ -61,7 +61,7 @@ const SignInForm = () => {
|
||||
return ui.setNotification({
|
||||
id: toastId,
|
||||
category: 'error',
|
||||
message: 'Please click the link sent to your email to confirm your account',
|
||||
message: 'Account has not been verified, please check the link sent to your email',
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@ const signUpSchema = passwordSchema.shape({
|
||||
const SignUpForm = () => {
|
||||
const { ui } = useStore()
|
||||
const captchaRef = useRef<HCaptcha>(null)
|
||||
const [showConditions, setShowConditions] = useState(false)
|
||||
const [isSubmitted, setIsSubmitted] = useState(false)
|
||||
const [passwordHidden, setPasswordHidden] = useState(true)
|
||||
const [captchaToken, setCaptchaToken] = useState<string | null>(null)
|
||||
@@ -107,16 +108,24 @@ const SignUpForm = () => {
|
||||
placeholder="••••••••"
|
||||
disabled={isSubmitting}
|
||||
autoComplete="new-password"
|
||||
onFocus={() => setShowConditions(true)}
|
||||
actions={
|
||||
<Button
|
||||
icon={passwordHidden ? <IconEye /> : <IconEyeOff />}
|
||||
type="default"
|
||||
className="!mr-1"
|
||||
onClick={() => setPasswordHidden((prev) => !prev)}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
|
||||
<PasswordConditionsHelper password={values.password} />
|
||||
<div
|
||||
className={`${
|
||||
showConditions ? 'max-h-[500px]' : 'max-h-[0px]'
|
||||
} transition-all duration-400 overflow-y-hidden`}
|
||||
>
|
||||
<PasswordConditionsHelper password={values.password} />
|
||||
</div>
|
||||
|
||||
<div className="self-center">
|
||||
<HCaptcha
|
||||
@@ -137,7 +146,7 @@ const SignUpForm = () => {
|
||||
form="signUp-form"
|
||||
htmlType="submit"
|
||||
size="large"
|
||||
disabled={isSubmitting}
|
||||
disabled={values.password.length === 0 || isSubmitting}
|
||||
loading={isSubmitting}
|
||||
>
|
||||
Sign Up
|
||||
|
||||
+25
-30
@@ -1,6 +1,6 @@
|
||||
import { observer } from 'mobx-react-lite'
|
||||
import { useEffect, useState } from 'react'
|
||||
import { IconArrowRight, IconMoon, IconSun, Input, Listbox } from 'ui'
|
||||
import { Button, IconArrowRight, IconMoon, IconSun, Input, Listbox } from 'ui'
|
||||
|
||||
import { Session } from '@supabase/supabase-js'
|
||||
import { AccountLayout } from 'components/layouts'
|
||||
@@ -60,46 +60,25 @@ const ProfileCard = observer(() => {
|
||||
const [session, setSession] = useState<Session | null>(null)
|
||||
|
||||
useEffect(() => {
|
||||
let cancel = false
|
||||
;(async () => {
|
||||
const {
|
||||
data: { session },
|
||||
} = await auth.getSession()
|
||||
|
||||
if (session) {
|
||||
setSession(session)
|
||||
}
|
||||
if (session && !cancel) setSession(session)
|
||||
})()
|
||||
|
||||
return () => {
|
||||
cancel = true
|
||||
}
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<article className="max-w-4xl p-4">
|
||||
<section>
|
||||
<Profile />
|
||||
<Profile session={session} />
|
||||
</section>
|
||||
|
||||
{session?.user.app_metadata.provider === 'email' && (
|
||||
<section>
|
||||
<Panel
|
||||
title={
|
||||
<h5 key="panel-title" className="mb-0">
|
||||
Password
|
||||
</h5>
|
||||
}
|
||||
>
|
||||
<Panel.Content>
|
||||
<div>
|
||||
You can change your password on the{' '}
|
||||
<Link href="/reset-password">
|
||||
<a className="text-blue-1000 hover:text-blue-1100 transition">
|
||||
password reset page <IconArrowRight width={16} height={16} className="inline" />
|
||||
</a>
|
||||
</Link>
|
||||
</div>
|
||||
</Panel.Content>
|
||||
</Panel>
|
||||
</section>
|
||||
)}
|
||||
|
||||
<section>
|
||||
{/* @ts-ignore */}
|
||||
<SchemaFormPanel
|
||||
@@ -127,7 +106,7 @@ const ProfileCard = observer(() => {
|
||||
)
|
||||
})
|
||||
|
||||
const Profile = observer(() => {
|
||||
const Profile = observer(({ session }: any) => {
|
||||
const { ui } = useStore()
|
||||
|
||||
return (
|
||||
@@ -154,6 +133,22 @@ const Profile = observer(() => {
|
||||
layout="horizontal"
|
||||
value={ui.profile?.primary_email ?? ''}
|
||||
/>
|
||||
{session?.user.app_metadata.provider === 'email' && (
|
||||
<div className="text-sm grid gap-2 md:grid md:grid-cols-12 md:gap-x-4">
|
||||
<div className="flex flex-col space-y-2 col-span-4 ">
|
||||
<p className="text-scale-1100 break-all">Password</p>
|
||||
</div>
|
||||
<div className="col-span-8">
|
||||
<Link href="/reset-password">
|
||||
<a>
|
||||
<Button type="default" size="medium">
|
||||
Reset password
|
||||
</Button>
|
||||
</a>
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</Panel.Content>
|
||||
</Panel>
|
||||
|
||||
@@ -32,7 +32,7 @@ const JoinOrganizationPage = () => {
|
||||
const { token_does_not_exist, email_match, expired_token, organization_name, invite_id } =
|
||||
tokenValidationInfo || {}
|
||||
|
||||
const loginRedirectLink = `/?next=${encodeURIComponent(`/join?token=${token}&slug=${slug}`)}`
|
||||
const loginRedirectLink = `/?returnTo=${encodeURIComponent(`/join?token=${token}&slug=${slug}`)}`
|
||||
|
||||
useEffect(() => {
|
||||
const fetchTokenInfo = async () => {
|
||||
|
||||
@@ -1,42 +1,11 @@
|
||||
import SignInForm from 'components/interfaces/SignIn/SignInForm'
|
||||
import SignInWithGitHub from 'components/interfaces/SignIn/SignInWithGitHub'
|
||||
import { SignInLayout } from 'components/layouts'
|
||||
import Connecting from 'components/ui/Loading'
|
||||
import { auth } from 'lib/gotrue'
|
||||
import Link from 'next/link'
|
||||
import { NextRouter, useRouter } from 'next/router'
|
||||
import { useEffect } from 'react'
|
||||
import { NextPageWithLayout } from 'types'
|
||||
|
||||
// detect for redirect from 3rd party service like vercel, aws...
|
||||
const isRedirectFromThirdPartyService = (router: NextRouter) => router.query.next !== undefined
|
||||
|
||||
const SignInPage: NextPageWithLayout = () => {
|
||||
const router = useRouter()
|
||||
const autoSignIn = isRedirectFromThirdPartyService(router)
|
||||
|
||||
useEffect(() => {
|
||||
if (autoSignIn) {
|
||||
const queryParams = (router.query as any) || {}
|
||||
const params = new URLSearchParams(queryParams)
|
||||
|
||||
// trigger github signIn
|
||||
auth.signInWithOAuth({
|
||||
provider: 'github',
|
||||
options: {
|
||||
redirectTo: `${
|
||||
process.env.NEXT_PUBLIC_VERCEL_ENV === 'preview'
|
||||
? process.env.NEXT_PUBLIC_VERCEL_URL
|
||||
: process.env.NEXT_PUBLIC_SITE_URL
|
||||
}?${params.toString()}`,
|
||||
},
|
||||
})
|
||||
}
|
||||
}, [])
|
||||
|
||||
return autoSignIn ? (
|
||||
<Connecting />
|
||||
) : (
|
||||
return (
|
||||
<>
|
||||
<div className="flex flex-col gap-5">
|
||||
<SignInWithGitHub />
|
||||
|
||||
Reference in new issue
Block a user