Skip to content

Adds Event and Callback for submit and before-submit #24

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
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
38 changes: 37 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ Customizable authentication UI component with custom themes and extensible style
- [Options](#options)
- [Supported Views](#supported-views)
- [Anonymous Sign-ins](#anonymous-sign-ins)
- [Events and Callbacks](#events-and-callbacks)
- [Customization](#customization)
- [Predefined themes](#predefined-themes)
- [Switch theme variations](#switch-theme-variations)
Expand Down Expand Up @@ -247,7 +248,42 @@ const { data, error } = await supabase.auth.signInAnonymously()
[Enable manual linking](https://supabase.com/dashboard/project/_/settings/auth) in supabase

Currently works for magic link and social login.
If you use password login, you need user to update password after he
If you use password login, you need user to update password after he sign in.

### Events and Callbacks

Control the authentication flow with the `beforeSubmit` callback and `on-submit` event.

- `beforeSubmit`: A function that runs before form submission. Return `false` to abort.
- `on-submit`: An event emitted with the user's email after submission.

```html
<template>
...
<Auth
:supabaseClient="supabaseClient"
:before-submit="handleBeforeSubmit"
@on-submit="handleSubmit"
/>
...
</template>

<script setup lang="ts">
import { Auth } from '@supa-kit/auth-ui-vue'

const handleBeforeSubmit = async (email: string) => {
if (email.endsWith('@example.com')) {
alert('Emails from @example.com are not allowed.')
return false // This will stop the submission
}
return true
}

const handleSubmit = (email: string) => {
console.log('Form submitted with email:', email)
}
</script>
```

## Customization

Expand Down
12 changes: 11 additions & 1 deletion packages/auth/Auth.vue
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
:showLinks="showLinks"
:i18n="i18n"
:additionalData="additionalData"
:before-submit="props.beforeSubmit"
@on-submit="handleSubmit"
/>
<MagicLink
v-if="authView === VIEWS.MAGIC_LINK"
Expand All @@ -36,6 +38,8 @@
:redirectTo="redirectTo"
:showLinks="showLinks"
:i18n="i18n"
:before-submit="props.beforeSubmit"
@on-submit="handleSubmit"
/>
</template>
</SocialAuthContainer>
Expand All @@ -47,6 +51,8 @@
:redirectTo="redirectTo"
:showLinks="showLinks"
:i18n="i18n"
:before-submit="props.beforeSubmit"
@on-submit="handleSubmit"
/>
<UpdatePassword
v-if="authView === VIEWS.UPDATE_PASSWORD"
Expand Down Expand Up @@ -101,14 +107,18 @@ const props = withDefaults(defineProps<AuthProps>(), {
anonymouslyCredentials: undefined
})

const emit = defineEmits(['update:view'])
const emit = defineEmits(['update:view', 'on-submit'])

const authView = ref<AuthViewType>(props.view)
const setAuthView = (newView: AuthViewType) => {
emit('update:view', newView)
authView.value = newView
}

const handleSubmit = (e: Event) => {
emit('on-submit', e)
}

provide(AuthViewKey, {
authView,
setAuthView
Expand Down
13 changes: 12 additions & 1 deletion packages/auth/EmailAuth.vue
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,6 @@ import {
} from '../types'
import {
Anchor,
Button,
BrandButton,
Container,
Input,
Expand All @@ -135,10 +134,13 @@ export interface EmailAuthProps {
showLinks?: boolean
i18n?: AuthI18nVariables
additionalData?: { [key: string]: any }
beforeSubmit?: (email: string) => Promise<boolean | void> | boolean | void
}

const props = withDefaults(defineProps<EmailAuthProps>(), {})

const emit = defineEmits(['on-submit'])

const email = ref('')
const password = ref('')
const error = ref('')
Expand All @@ -151,12 +153,20 @@ const labels = computed(
() => props.i18n?.[authView.value] as AuthI18nVariables['sign_in' | 'sign_up']
)
const handleSubmit = async (e: Event) => {
if (props.beforeSubmit) {
const canSubmit = await props.beforeSubmit(email.value)
if (canSubmit === false) {
return
}
}

// console.log(props)
error.value = ''
message.value = ''
isLoading.value = true
switch (authView.value) {
case 'sign_in':
emit('on-submit', email.value)
const {
// data: { user: signInUser, session: signInSession },
error: signInError
Expand All @@ -176,6 +186,7 @@ const handleSubmit = async (e: Event) => {
if (props.additionalData) {
options.data = props.additionalData
}
emit('on-submit', email.value)
const {
data: { user: signUpUser, session: signUpSession },
error: signUpError
Expand Down
9 changes: 9 additions & 0 deletions packages/auth/ForgottenPassword.vue
Original file line number Diff line number Diff line change
Expand Up @@ -82,9 +82,11 @@ export interface ForgottenPasswordProps {
redirectTo?: RedirectTo
showLinks?: boolean
i18n?: AuthI18nVariables
beforeSubmit?: (email: string) => Promise<boolean | void> | boolean | void
}

const props = withDefaults(defineProps<ForgottenPasswordProps>(), {})
const emit = defineEmits(['on-submit'])

const email = ref('')
const error = ref('')
Expand All @@ -98,6 +100,13 @@ const labels = computed(
)

const handleSubmit = async (e: Event) => {
if (props.beforeSubmit) {
const canSubmit = await props.beforeSubmit(email.value)
if (canSubmit === false) {
return
}
}
emit('on-submit', email.value)
// console.log(props)
error.value = ''
message.value = ''
Expand Down
15 changes: 15 additions & 0 deletions packages/auth/MagicLink.vue
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,15 @@ export interface MagicLinkProps {
redirectTo?: RedirectTo
showLinks?: boolean
i18n?: AuthI18nVariables
/**
* A function that will be called before the magic link is sent.
* If the function returns `false`, the submission will be aborted.
*/
beforeSubmit?: (email: string) => Promise<boolean | void> | boolean | void
}

const emit = defineEmits(['on-submit'])

const props = withDefaults(defineProps<MagicLinkProps>(), {})

const { supabaseUser } = useSupabaseUser(props.supabaseClient)
Expand All @@ -101,12 +108,20 @@ const labels = computed(
)

const handleSubmit = async (e: Event) => {
if (props.beforeSubmit) {
const canSubmit = await props.beforeSubmit(email.value)
if (canSubmit === false) {
return
}
}

// console.log(props)
error.value = ''
message.value = ''
isLoading.value = true
const isAnonymous = supabaseUser.value?.is_anonymous
let signInError: Error | null = null
emit('on-submit', email.value)
if (isAnonymous) {
const { error: err } = await props.supabaseClient.auth.updateUser(
{
Expand Down
5 changes: 5 additions & 0 deletions packages/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,11 @@ export interface AuthProps extends BaseAuth {
variables?: AuthI18nVariables
}
anonymouslyCredentials?: SignInAnonymouslyCredentials
/**
* A function that will be called before the authentication is submitted.
* If the function returns `false`, the submission will be aborted.
*/
beforeSubmit?: (email: string) => Promise<boolean | void> | boolean | void
}

export type AuthProvider =
Expand Down
14 changes: 14 additions & 0 deletions src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@
variables: I18nVariables
}"
:redirect-to="redirectTo"
:before-submit="handleEmailSubmit"
@on-submit="handleSubmit"
show-links
/>
</div>
Expand Down Expand Up @@ -320,6 +322,18 @@ const handleSignOut = () => {
supabaseUser.value = null
}

const handleEmailSubmit = async (email: string) => {
if (email.endsWith('@suspicious.com')) {
alert('This email provider is not allowed.')
return false
}
return true
}

const handleSubmit = (event: Event) => {
console.log(event)
}

watch(
() => supabaseUser.value,
(newUser) => {
Expand Down