Skip to content

Commit fa7038e

Browse files
authored
doc: migrate supabase auth guide to v3 (#518)
* doc: migrate supabase auth guide to v3 * update
1 parent b66373c commit fa7038e

File tree

8 files changed

+93
-16
lines changed

8 files changed

+93
-16
lines changed

versioned_docs/version-3.x/modeling/attribute.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ By convention, attributes attached to models use a double `@@` prefix, while tho
1515

1616
```zmodel
1717
model User {
18-
id Int @id
19-
email String @unique
18+
id Int @id
19+
email String @unique
2020
2121
@@index([email, name])
2222
}

versioned_docs/version-3.x/modeling/index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ model User {
3232
}
3333
3434
model Post {
35-
id Int @id @default(autoincrement())
35+
id Int @id @default(autoincrement())
3636
createdAt DateTime @default(now())
3737
updatedAt DateTime @updatedAt
3838
title String

versioned_docs/version-3.x/modeling/model.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ If your model needs a composite ID, you can use the `@@id` model-level attribute
3535
```zmodel
3636
model City {
3737
country String
38-
name String
38+
name String
3939
// highlight-next-line
4040
@@id([country, name])
4141
}
@@ -51,7 +51,7 @@ model User {
5151
5252
model City {
5353
country String
54-
name String
54+
name String
5555
// highlight-next-line
5656
@@unique([country, name])
5757
}
@@ -95,7 +95,7 @@ Each model field must at least have a name and a type. A field can be typed in o
9595
}
9696
9797
model User {
98-
id Int @id
98+
id Int @id
9999
// highlight-next-line
100100
role Role
101101
}
@@ -107,9 +107,9 @@ Each model field must at least have a name and a type. A field can be typed in o
107107

108108
```zmodel
109109
model Post {
110-
id Int @id
110+
id Int @id
111111
// highlight-next-line
112-
author User @relation(fields: [authorId], references: [id])
112+
author User @relation(fields: [authorId], references: [id])
113113
authorId Int
114114
}
115115
```
@@ -126,7 +126,7 @@ Each model field must at least have a name and a type. A field can be typed in o
126126
}
127127
128128
model User {
129-
id Int @id
129+
id Int @id
130130
// highlight-next-line
131131
address Address @json
132132
}
@@ -136,7 +136,7 @@ A field can be set as optional by adding the `?` suffix to its type, or list by
136136

137137
```zmodel
138138
model User {
139-
id Int @id
139+
id Int @id
140140
// highlight-next-line
141141
name String?
142142
// highlight-next-line

versioned_docs/version-3.x/modeling/polymorphism.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ There are two special things about a polymorphic base model:
106106

107107
You can also have a deep hierarchy involving multiple levels of base models. Just need to make sure each base model has its own discriminator field and `@@delegate` attribute. Extending from multiple base models directly is not supported.
108108

109-
## Migration behavior
109+
## Database schema
110110

111111
The migration engine takes care of mapping both the base model and the concrete ones to tables, and creates one-to-one relations between the base and each of its derivations.
112112

versioned_docs/version-3.x/modeling/relation.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -73,14 +73,14 @@ A typical one-to-many relation looks like this:
7373

7474
```zmodel
7575
model User {
76-
id Int @id
77-
posts Post[]
76+
id Int @id
77+
posts Post[]
7878
}
7979
8080
model Post {
81-
id Int @id
82-
author User @relation(fields: [authorId], references: [id])
83-
authorId Int
81+
id Int @id
82+
author User @relation(fields: [authorId], references: [id])
83+
authorId Int
8484
}
8585
```
8686

versioned_docs/version-3.x/recipe/_category_.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,6 @@ position: 7
22
label: Recipes
33
collapsible: true
44
collapsed: true
5+
link:
6+
type: generated-index
7+
title: Recipes

versioned_docs/version-3.x/recipe/auth-integration/_category_.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,6 @@ position: 1
22
label: Integrating With Authentication
33
collapsible: true
44
collapsed: true
5+
link:
6+
type: generated-index
7+
title: Recipes
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
---
2+
description: Integrating with Supabase Auth.
3+
sidebar_position: 4
4+
sidebar_label: Supabase Auth
5+
---
6+
7+
# Integrating With Supabase Auth
8+
9+
[Supabase](https://supabase.com) is a comprehensive Backend-as-a-Service that offers database, authentication, and other services.
10+
11+
To get access policies to work, ZenStack needs to be connected to the authentication system to get the user's identity. If you use Supabase as your authentication provider, this document will guide you through integrating ZenStack with it.
12+
13+
## Syncing Supabase Auth users to your database
14+
15+
:::info
16+
This section is only relevant if you're also using Supabase's Database service as the underlying Postgres database of ZenStack.
17+
:::
18+
19+
Supabase Auth stores user data in a separate Postgres schema called "auth". Since that schema is managed by Supabase, it's good idea NOT to directly import it into ZModel and use it in your application. Instead, if you want to have a synchronized copy of the data, refer to [Supabase's user management documentation](https://supabase.com/docs/guides/auth/managing-user-data) for how to set up database triggers and keep your user table in sync with Supabase Auth.
20+
21+
## Creating a user-bound ORM client
22+
23+
Supabase provides the `@supabase/ssr` package to help with server-side authentication. Please refer to [its documentation](https://supabase.com/docs/guides/auth/server-side) for full details. The following example shows how to do it in a Next.js application.
24+
25+
```ts
26+
import { createServerClient } from '@supabase/ssr'
27+
import { cookies } from 'next/headers'
28+
import { db } from '@/lib/db' // your ZenStackClient instance
29+
30+
// create a Supabase SSR client
31+
async function createSupabaseSSRClient() {
32+
const cookieStore = await cookies()
33+
return createServerClient(
34+
process.env.NEXT_PUBLIC_SUPABASE_URL!,
35+
process.env.NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY!,
36+
{
37+
cookies: {
38+
getAll() {
39+
return cookieStore.getAll()
40+
},
41+
setAll(cookiesToSet) {
42+
try {
43+
cookiesToSet.forEach(({ name, value }) => cookieStore.set(name, value))
44+
} catch {
45+
// The `setAll` method was called from a Server Component.
46+
// This can be ignored if you have middleware refreshing
47+
// user sessions.
48+
}
49+
},
50+
},
51+
}
52+
)
53+
}
54+
55+
// create a user-bound ORM client
56+
async function getUserDb() {
57+
const supabase = await createSupabaseSSRClient();
58+
const { data: { user } } = await supabase.auth.getUser()
59+
60+
// you can selectively include fields into the context object
61+
// depending on what your access policies need
62+
const contextUser = user ? { id: user.id } : undefined;
63+
return db.$setAuth(contextUser);
64+
}
65+
```
66+
67+
:::warning
68+
It may be tempting to call the `supabase.auth.getSession()` API to get the current user. However, the data returned is not validated by Supabase's service, so it must not be trusted.
69+
:::
70+
71+
You can then use this user-bound ORM client for CRUD operations governed by the access policies you defined in ZModel.

0 commit comments

Comments
 (0)