mirror of
https://github.com/supabase/supabase.git
synced 2026-10-05 17:35:10 +03:00
Merge pull request #9456 from supabase/thor/egde-function-auth-rls-example-improvements
chore: update functions examples to supabase-js v2
This commit is contained in:
4 files changed
+65
-39
No files matched your search
@@ -3,8 +3,8 @@
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@supabase/supabase-js": "^1.33.3",
|
||||
"@supabase/ui": "^0.36.4",
|
||||
"@supabase/auth-ui-react": "^0.2.1",
|
||||
"@supabase/supabase-js": "^2.0.0-rc.12",
|
||||
"@testing-library/jest-dom": "^5.16.3",
|
||||
"@testing-library/react": "^12.1.4",
|
||||
"@testing-library/user-event": "^13.5.0",
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
import React, { useState } from 'react'
|
||||
import { Auth, Button, Typography, Select } from '@supabase/ui'
|
||||
import { Auth, ThemeSupa } from '@supabase/auth-ui-react'
|
||||
import JSONInput from 'react-json-editor-ajrm'
|
||||
import locale from 'react-json-editor-ajrm/locale/en'
|
||||
import { supabase } from './utils/supabaseClient'
|
||||
import { functionsList } from './functionsList'
|
||||
|
||||
const { Title, Text } = Typography
|
||||
const sampleObject = { name: 'world' }
|
||||
|
||||
function App() {
|
||||
@@ -25,29 +24,40 @@ function App() {
|
||||
|
||||
return (
|
||||
<div className="p-2">
|
||||
<Title level={2} className="mb-2">
|
||||
Supabase Egde Functions Test Client
|
||||
</Title>
|
||||
<h2 className="mb-2 text-4xl">Supabase Egde Functions Test Client</h2>
|
||||
<div className="grid grid-cols-1 md:grid-cols-2">
|
||||
<div className="p-2">
|
||||
<Title level={3} className="mb-2">
|
||||
Request
|
||||
</Title>
|
||||
<Title level={4}>Function</Title>
|
||||
<Select onChange={(e) => setSupaFunction(e.target.value)}>
|
||||
<h3 className="mb-2 text-3xl">Request</h3>
|
||||
<h4 className="text-2xl">Function</h4>
|
||||
<select
|
||||
className="form-select m-0focus:border-green-600
|
||||
block
|
||||
w-full
|
||||
appearance-none
|
||||
rounded
|
||||
border
|
||||
border-solid
|
||||
border-gray-300
|
||||
bg-white bg-clip-padding bg-no-repeat
|
||||
px-3 py-1.5 text-base
|
||||
font-normal
|
||||
text-gray-700
|
||||
transition
|
||||
ease-in-out
|
||||
focus:bg-white focus:text-gray-700 focus:outline-none"
|
||||
onChange={(e) => setSupaFunction(e.target.value)}
|
||||
>
|
||||
{functionsList.map((func) => (
|
||||
<Select.Option value={func} key={func}>
|
||||
<option value={func} key={func}>
|
||||
{func}
|
||||
</Select.Option>
|
||||
</option>
|
||||
))}
|
||||
</Select>
|
||||
<Text className="mb-2">
|
||||
</select>
|
||||
<p className="mb-2">
|
||||
Note: when using locally, this selection doesn't have any effect and the function that's
|
||||
currently being served via the CLI is called instead.
|
||||
</Text>
|
||||
<Title level={4} className="mb-2">
|
||||
Body
|
||||
</Title>
|
||||
</p>
|
||||
<h4 className="mb-2 text-2xl">Body</h4>
|
||||
<JSONInput
|
||||
onChange={({ jsObject }) => setRequestJson(jsObject)}
|
||||
placeholder={sampleObject}
|
||||
@@ -55,27 +65,31 @@ function App() {
|
||||
height="100"
|
||||
width="100%"
|
||||
/>
|
||||
<Button className="mt-2" onClick={invokeFunction}>
|
||||
<button
|
||||
className="mt-2 rounded bg-green-500 py-2 px-4 font-bold text-white hover:bg-green-700"
|
||||
onClick={invokeFunction}
|
||||
>
|
||||
Invoke Function
|
||||
</Button>
|
||||
</button>
|
||||
</div>
|
||||
<div className="p-2">
|
||||
<Title level={3} className="mb-2">
|
||||
Response
|
||||
</Title>
|
||||
<pre className="p-2 bg-gray-300 ">{JSON.stringify(responseJson, null, 2)}</pre>
|
||||
<h3 className="mb-2 text-3xl">Response</h3>
|
||||
<pre className="bg-gray-300 p-2 ">{JSON.stringify(responseJson, null, 2)}</pre>
|
||||
</div>
|
||||
<div className="p-2">
|
||||
<Title level={3} className="mb-2">
|
||||
Log in to see RLS in action
|
||||
</Title>
|
||||
<h3 className="mb-2 text-3xl">Log in to see RLS in action</h3>
|
||||
{user ? (
|
||||
<div>
|
||||
<Title level={4} className="mb-2">{`Logged in as ${user.email}`}</Title>
|
||||
<Button onClick={() => supabase.auth.signOut()}>Sign out</Button>
|
||||
<h4 className="mb-2 text-2xl">{`Logged in as ${user.email}`}</h4>
|
||||
<button
|
||||
className="rounded bg-green-500 py-2 px-4 font-bold text-white hover:bg-green-700"
|
||||
onClick={() => supabase.auth.signOut()}
|
||||
>
|
||||
Sign out
|
||||
</button>
|
||||
</div>
|
||||
) : (
|
||||
<Auth supabaseClient={supabase} />
|
||||
<Auth supabaseClient={supabase} appearance={{ theme: ThemeSupa }} />
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -2,7 +2,7 @@ import React from 'react'
|
||||
import ReactDOM from 'react-dom'
|
||||
import './index.css'
|
||||
import App from './App'
|
||||
import { Auth } from '@supabase/ui'
|
||||
import { Auth } from '@supabase/auth-ui-react'
|
||||
import { supabase } from './utils/supabaseClient'
|
||||
|
||||
ReactDOM.render(
|
||||
|
||||
+18
-6
@@ -3,7 +3,7 @@
|
||||
// This enables autocomplete, go to definition, etc.
|
||||
|
||||
import { serve } from 'https://deno.land/std@0.131.0/http/server.ts'
|
||||
import { supabaseClient } from '../_shared/supabaseClient.ts'
|
||||
import { createClient } from 'https://esm.sh/@supabase/supabase-js@2.0.0-rc.12'
|
||||
import { corsHeaders } from '../_shared/cors.ts'
|
||||
|
||||
console.log(`Function "select-from-table-with-auth-rls" up and running!`)
|
||||
@@ -15,14 +15,26 @@ serve(async (req: Request) => {
|
||||
}
|
||||
|
||||
try {
|
||||
// Set the Auth context of the user that called the function.
|
||||
// This way your row-level-security (RLS) policies are applied.
|
||||
supabaseClient.auth.setAuth(req.headers.get('Authorization')!.replace('Bearer ', ''))
|
||||
// Create a Supabase client with the Auth context of the logged in user.
|
||||
const supabaseClient = createClient(
|
||||
// Supabase API URL - env var exported by default.
|
||||
Deno.env.get('SUPABASE_URL') ?? '',
|
||||
// Supabase API ANON KEY - env var exported by default.
|
||||
Deno.env.get('SUPABASE_ANON_KEY') ?? '',
|
||||
// Create client with Auth context of the user that called the function.
|
||||
// This way your row-level-security (RLS) policies are applied.
|
||||
{ global: { headers: { Authorization: req.headers.get('Authorization')! } } }
|
||||
)
|
||||
// Now we can get the session or user object
|
||||
const {
|
||||
data: { user },
|
||||
} = await supabaseClient.auth.getUser()
|
||||
|
||||
// And we can run queries in the context of our authenticated user
|
||||
const { data, error } = await supabaseClient.from('users').select('*')
|
||||
console.log({ data, error })
|
||||
if (error) throw error
|
||||
|
||||
return new Response(JSON.stringify({ data, error }), {
|
||||
return new Response(JSON.stringify({ user, data }), {
|
||||
headers: { ...corsHeaders, 'Content-Type': 'application/json' },
|
||||
status: 200,
|
||||
})
|
||||
|
||||
Reference in new issue
Block a user