@plutocms/supabase 0.10.0 → 0.11.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,95 +0,0 @@
1
- <script setup lang="ts">
2
- interface Form {
3
- email: string
4
- password: string
5
- }
6
-
7
- definePageMeta({
8
- layout: 'auth',
9
- })
10
-
11
- const { t } = usePlutoI18n()
12
-
13
- useHead({
14
- title: () => t('supabase.auth.login.title'),
15
- })
16
-
17
- const { isSubmitting, login } = await useAuth()
18
-
19
- const form = ref<Form>({
20
- email: '',
21
- password: '',
22
- })
23
-
24
- function submitForm() {
25
- login(form.value)
26
- }
27
- </script>
28
-
29
- <template>
30
- <div class="grid min-h-dvh place-items-center p-4">
31
- <UCard class="w-full max-w-100">
32
- <form @submit.prevent="submitForm">
33
- <div class="flex flex-col gap-y-6">
34
- <h1 class="text-3xl font-bold">{{ t('supabase.auth.login.title') }}</h1>
35
-
36
- <UFormField :label="t('supabase.auth.fields.email')">
37
- <UInput
38
- v-model="form.email"
39
- placeholder="victor@example.com"
40
- class="w-full"
41
- autocomplete="email"
42
- />
43
- </UFormField>
44
-
45
- <UFormField :label="t('supabase.auth.fields.password')">
46
- <UInput
47
- v-model="form.password"
48
- placeholder="••••"
49
- class="w-full"
50
- type="password"
51
- />
52
- </UFormField>
53
-
54
- <div
55
- class="flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between sm:gap-x-4"
56
- >
57
- <UFormField>
58
- <UButton
59
- :loading="isSubmitting"
60
- type="submit"
61
- icon="lucide:log-in"
62
- class="w-full justify-center sm:w-auto"
63
- >
64
- {{ t('supabase.auth.login.submit') }}
65
- </UButton>
66
- </UFormField>
67
-
68
- <UFormField>
69
- <UButton variant="link" to="/admin/signup" class="px-0">
70
- {{ t('supabase.auth.login.createAccount') }}
71
- </UButton>
72
- </UFormField>
73
- </div>
74
-
75
- <div
76
- class="flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between"
77
- >
78
- <UButton
79
- variant="link"
80
- icon="lucide:arrow-left"
81
- to="/"
82
- class="px-0"
83
- >
84
- {{ t('supabase.auth.login.backToHome') }}
85
- </UButton>
86
-
87
- <UButton variant="link" to="/admin/forgot-password" class="px-0">
88
- {{ t('supabase.auth.login.forgotPassword') }}
89
- </UButton>
90
- </div>
91
- </div>
92
- </form>
93
- </UCard>
94
- </div>
95
- </template>
@@ -1,57 +0,0 @@
1
- <script setup lang="ts">
2
- definePageMeta({
3
- middleware: ['setup-check', 'auth'],
4
- layout: 'admin',
5
- })
6
-
7
- const route = useRoute()
8
- const { t } = usePlutoI18n()
9
- const { isLoggedIn, logout, allowedUnauthenticatedPaths } = await useAuth()
10
- const toast = useToast()
11
-
12
- // Loading/clearing permissions on login/logout lives in
13
- // app/plugins/pluto-permissions-sync.ts now, not here — that plugin runs
14
- // on every page, not just this one, so a signed-in admin browsing a public
15
- // page directly (no prior visit to /admin/** this session) still gets
16
- // their capabilities loaded.
17
-
18
- const visibility = useDocumentVisibility()
19
-
20
- watch(visibility, async (current, previous) => {
21
- if (current === 'visible' && previous === 'hidden') {
22
- if (
23
- !isLoggedIn.value &&
24
- !route.path.startsWith('/admin/setup') &&
25
- !allowedUnauthenticatedPaths.includes(route.path)
26
- ) {
27
- await logout({ redirectTo: route.path })
28
-
29
- toast.add({
30
- title: t('supabase.auth.toasts.notLoggedIn'),
31
- description: t('supabase.auth.toasts.notLoggedInDescription'),
32
- icon: 'lucide:circle-x',
33
- color: 'error',
34
- })
35
- }
36
- }
37
- })
38
- </script>
39
-
40
- <template>
41
- <div class="light:text-zinc-800 h-full dark:text-white">
42
- <ClientOnly>
43
- <Container
44
- v-if="
45
- isLoggedIn
46
- && !route.path.startsWith('/admin/setup')
47
- && !route.path.startsWith('/admin/migrations')
48
- "
49
- class="pt-4"
50
- >
51
- <MigrationsBanner />
52
- </Container>
53
- </ClientOnly>
54
-
55
- <NuxtPage />
56
- </div>
57
- </template>
@@ -1,30 +0,0 @@
1
- /**
2
- * Loads the signed-in user's stored admin language whenever a session
3
- * appears: after a login, and on a page load that already has a session.
4
- * App-wide, like pluto-permissions-sync.ts, so any page gets the language,
5
- * not only the pages under /admin.
6
- *
7
- * Client-only, unlike the permissions sync. A server `$fetch` does not forward
8
- * the user's cookies, so a server run would read no locale and clear the cookie.
9
- * The server already resolves the first locale from the cookie or the
10
- * Accept-Language header. The stored value then replaces it on the client, and
11
- * the cookie keeps it for the next server render.
12
- *
13
- * `useSupabaseSession()` is the same primitive the permissions sync uses.
14
- * `syncUserLocale()` never throws. With no driver, or on an error, nothing
15
- * changes.
16
- */
17
- export default defineNuxtPlugin(() => {
18
- const session = useSupabaseSession()
19
- const { syncUserLocale } = usePlutoI18n()
20
-
21
- watch(
22
- session,
23
- (current) => {
24
- if (current) {
25
- void syncUserLocale()
26
- }
27
- },
28
- { immediate: true }
29
- )
30
- })
@@ -1,38 +0,0 @@
1
- /**
2
- * Loads (or clears) the current user's capabilities whenever their session
3
- * appears or disappears — app-wide, not page-scoped.
4
- *
5
- * This used to live as a `watch` inside `app/pages/admin.vue`. That only
6
- * ran while `admin.vue` was the mounted page, so a signed-in admin loading
7
- * a public page directly (a fresh navigation or a page reload, with no
8
- * earlier visit to `/admin/**` in the same app instance) never triggered a
9
- * load at all — `usePlutoPermissions().granted` stayed empty, and every
10
- * `can()` check for that admin read as `false` on that page, even though
11
- * the same admin's capability-gated UI worked correctly inside `/admin/**`.
12
- * `NavbarAdminActions.vue`'s "Edit product" quick-link (shown while
13
- * viewing a live `/product/**` page) is exactly the kind of capability-
14
- * gated UI that lives outside `/admin/**` by design, so it needs this to
15
- * fire on every page, not just admin ones.
16
- *
17
- * `useSupabaseSession()` (not `useAuth()`) on purpose: it is the same
18
- * primitive `useAuth()`'s own `isLoggedIn` is built from
19
- * (`computed(() => !!supabaseSession.value)`), and it is genuinely
20
- * app-wide reactive state already (managed by `@nuxtjs/supabase`'s own
21
- * plugin), so reading it directly here needs no extra composable surface.
22
- */
23
- export default defineNuxtPlugin(() => {
24
- const session = useSupabaseSession()
25
- const { load, clear } = usePlutoPermissions()
26
-
27
- watch(
28
- session,
29
- (current) => {
30
- if (current) {
31
- load()
32
- } else {
33
- clear()
34
- }
35
- },
36
- { immediate: true }
37
- )
38
- })