diff --git a/apps/docs/content/guides/auth/auth-email-templates.mdx b/apps/docs/content/guides/auth/auth-email-templates.mdx
index 8f23b52a28414..7731d4f990a3c 100644
--- a/apps/docs/content/guides/auth/auth-email-templates.mdx
+++ b/apps/docs/content/guides/auth/auth-email-templates.mdx
@@ -71,20 +71,34 @@ For mobile applications, you might need to link or redirect to a specific page w
Certain email providers may have spam detection or other security features that prefetch URL links from incoming emails (e.g. [Safe Links in Microsoft Defender for Office 365](https://learn.microsoft.com/en-us/microsoft-365/security/office-365-security/safe-links-about?view=o365-worldwide)).
In this scenario, the `{{ .ConfirmationURL }}` sent will be consumed instantly which leads to a "Token has expired or is invalid" error.
-To guard against this:
+To guard against this there are the options below:
-- Use an email OTP instead by including `{{ .Token }}` in the email template.
-- Create your own custom email link to redirect the user to a page where they can click on a button to confirm the action.
- For example, you can include the following in your email template:
+**Option 1**
- ```html
- Confirm your signup
-
- ```
+- Use an email OTP instead by including `{{ .Token }}` in the email template
+- Create your own custom email link to redirect the user to a page where they can enter with their email and token to login
- The user should be brought to a page on your site where they can confirm the action by clicking a button.
- The button should contain the actual confirmation link which can be obtained from parsing the `confirmation_url={{ .ConfirmationURL }}` query parameter in the URL.
+```html
+Confirm your signup
+```
+
+- Log them in by verifying the OTP token value with their email e.g. with [`supabase.auth.verifyOtp`](/docs/reference/javascript/auth-verifyotp) show below
+
+```ts
+const { data, error } = await supabase.auth.verifyOtp({ email, token, type: 'email' })
+```
+
+**Option 2**
+
+- Create your own custom email link to redirect the user to a page where they can click on a button to confirm the action
+
+```html
+Confirm your signup
+```
+
+- The button should contain the actual confirmation link which can be obtained from parsing the `confirmation_url={{ .ConfirmationURL }}` query parameter in the URL.
### Email tracking
diff --git a/apps/studio/components/interfaces/Database/Triggers/TriggersList/TriggerList.tsx b/apps/studio/components/interfaces/Database/Triggers/TriggersList/TriggerList.tsx
index 0374a3758ee49..fa8681560a601 100644
--- a/apps/studio/components/interfaces/Database/Triggers/TriggersList/TriggerList.tsx
+++ b/apps/studio/components/interfaces/Database/Triggers/TriggersList/TriggerList.tsx
@@ -1,9 +1,12 @@
+import { PostgresTrigger } from '@supabase/postgres-meta'
import { PermissionAction } from '@supabase/shared-types/out/constants'
import { includes, sortBy } from 'lodash'
import { Check, Copy, Edit, Edit2, MoreVertical, Trash, X } from 'lucide-react'
-import { ButtonTooltip } from 'components/ui/ButtonTooltip'
+import { useParams } from 'common'
import { SIDEBAR_KEYS } from 'components/layouts/ProjectLayout/LayoutSidebar/LayoutSidebarProvider'
+import { ButtonTooltip } from 'components/ui/ButtonTooltip'
+import { InlineLink } from 'components/ui/InlineLink'
import { useDatabaseTriggersQuery } from 'data/database-triggers/database-triggers-query'
import { useAsyncCheckPermissions } from 'hooks/misc/useCheckPermissions'
import { useSelectedProjectQuery } from 'hooks/misc/useSelectedProject'
@@ -24,7 +27,6 @@ import {
TooltipTrigger,
} from 'ui'
import { generateTriggerCreateSQL } from './TriggerList.utils'
-import { PostgresTrigger } from '@supabase/postgres-meta'
interface TriggerListProps {
schema: string
@@ -35,7 +37,7 @@ interface TriggerListProps {
deleteTrigger: (trigger: PostgresTrigger) => void
}
-const TriggerList = ({
+export const TriggerList = ({
schema,
filterString,
isLocked,
@@ -43,10 +45,16 @@ const TriggerList = ({
duplicateTrigger,
deleteTrigger,
}: TriggerListProps) => {
+ const { ref: projectRef } = useParams()
const { data: project } = useSelectedProjectQuery()
const aiSnap = useAiAssistantStateSnapshot()
const { openSidebar } = useSidebarManagerSnapshot()
+ const { can: canUpdateTriggers } = useAsyncCheckPermissions(
+ PermissionAction.TENANT_SQL_ADMIN_WRITE,
+ 'triggers'
+ )
+
const { data: triggers } = useDatabaseTriggersQuery({
projectRef: project?.ref,
connectionString: project?.connectionString,
@@ -56,15 +64,10 @@ const TriggerList = ({
includes(x.name.toLowerCase(), filterString.toLowerCase()) ||
(x.function_name && includes(x.function_name.toLowerCase(), filterString.toLowerCase()))
)
-
const _triggers = sortBy(
filteredTriggers.filter((x) => x.schema == schema),
(trigger) => trigger.name.toLocaleLowerCase()
)
- const { can: canUpdateTriggers } = useAsyncCheckPermissions(
- PermissionAction.TENANT_SQL_ADMIN_WRITE,
- 'triggers'
- )
if (_triggers.length === 0 && filterString.length === 0) {
return (
@@ -94,7 +97,7 @@ const TriggerList = ({
return (
<>
- {_triggers.map((x: any) => (
+ {_triggers.map((x) => (
@@ -111,15 +114,33 @@ const TriggerList = ({
-