Skip to content

Commit a403f1c

Browse files
authored
feat: add publishable key in connect dialog (supabase#36638)
1 parent 63164fe commit a403f1c

File tree

20 files changed

+125
-73
lines changed

20 files changed

+125
-73
lines changed

apps/studio/components/interfaces/Connect/Connect.tsx

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,13 @@ import { PermissionAction } from '@supabase/shared-types/out/constants'
22
import { useParams } from 'common'
33
import { ExternalLink, Plug } from 'lucide-react'
44
import { parseAsBoolean, useQueryState } from 'nuqs'
5-
import { useState } from 'react'
5+
import { useState, useMemo } from 'react'
66

77
import { DatabaseConnectionString } from 'components/interfaces/Connect/DatabaseConnectionString'
88
import { ButtonTooltip } from 'components/ui/ButtonTooltip'
99
import Panel from 'components/ui/Panel'
1010
import { getAPIKeys, useProjectSettingsV2Query } from 'data/config/project-settings-v2-query'
11+
import { useAPIKeysQuery } from 'data/api-keys/api-keys-query'
1112
import { useCheckPermissions } from 'hooks/misc/useCheckPermissions'
1213
import { useSelectedProject } from 'hooks/misc/useSelectedProject'
1314
import { PROJECT_STATUS } from 'lib/constants'
@@ -137,13 +138,21 @@ export const Connect = () => {
137138
return []
138139
}
139140

140-
const protocol = settings?.app_config?.protocol ?? 'https'
141-
const endpoint = settings?.app_config?.endpoint ?? ''
142-
const apiHost = canReadAPIKeys ? `${protocol}://${endpoint ?? '-'}` : ''
143-
const apiUrl = canReadAPIKeys ? apiHost : null
144-
145141
const { anonKey } = canReadAPIKeys ? getAPIKeys(settings) : { anonKey: null }
146-
const projectKeys = { apiUrl, anonKey: anonKey?.api_key ?? null }
142+
const { data: apiKeys } = useAPIKeysQuery({ projectRef, reveal: false })
143+
144+
const projectKeys = useMemo(() => {
145+
const protocol = settings?.app_config?.protocol ?? 'https'
146+
const endpoint = settings?.app_config?.endpoint ?? ''
147+
const apiHost = canReadAPIKeys ? `${protocol}://${endpoint ?? '-'}` : ''
148+
149+
const apiUrl = canReadAPIKeys ? apiHost : null
150+
return {
151+
apiUrl: apiHost ?? null,
152+
anonKey: anonKey?.api_key ?? null,
153+
publishableKey: apiKeys?.find(({ type }) => type === 'publishable')?.api_key ?? null,
154+
}
155+
}, [apiKeys, anonKey, canReadAPIKeys, settings])
147156

148157
const filePath = getContentFilePath({
149158
connectionObject,

apps/studio/components/interfaces/Connect/Connect.types.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
export type projectKeys = {
22
apiUrl: string | null
33
anonKey: string | null
4+
publishableKey: string | null
45
}
56

67
export interface ContentFileProps {
78
projectKeys: {
89
apiUrl: string
9-
anonKey: string
10+
anonKey?: string
11+
publishableKey?: string
1012
}
1113
connectionStringPooler: {
1214
transactionShared: string

apps/studio/components/interfaces/Connect/content/androidkotlin/supabasekt/content.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ data class TodoItem(val id: Int, val name: String)
3030
{`
3131
val supabase = createSupabaseClient(
3232
supabaseUrl = "${projectKeys.apiUrl ?? 'your-project-url'}",
33-
supabaseKey = "${projectKeys.anonKey ?? 'your-anon-key'}"
33+
supabaseKey = "${projectKeys.publishableKey ?? '<prefer publishable key instead of anon key for mobile apps>'}"
3434
) {
3535
install(Postgrest)
3636
}

apps/studio/components/interfaces/Connect/content/astro/supabasejs/content.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ const ContentFile = ({ projectKeys }: ContentFileProps) => {
2121
<SimpleCodeBlock className="bash" parentClassName="min-h-72">
2222
{`
2323
SUPABASE_URL=${projectKeys.apiUrl ?? 'your-project-url'}
24-
SUPABASE_KEY=${projectKeys.anonKey ?? 'your-anon-key'}
24+
SUPABASE_KEY=${projectKeys.publishableKey ?? projectKeys.anonKey ?? 'your-anon-key'}
2525
`}
2626
</SimpleCodeBlock>
2727
</ConnectTabContent>

apps/studio/components/interfaces/Connect/content/exporeactnative/supabasejs/content.tsx

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ const ContentFile = ({ projectKeys }: ContentFileProps) => {
2121
<SimpleCodeBlock className="bash" parentClassName="min-h-72">
2222
{`
2323
EXPO_PUBLIC_SUPABASE_URL=${projectKeys.apiUrl ?? 'your-project-url'}
24-
EXPO_PUBLIC_SUPABASE_ANON_KEY=${projectKeys.anonKey ?? 'your-anon-key'}
24+
EXPO_PUBLIC_SUPABASE_KEY=${projectKeys.publishableKey ?? '<prefer publishable key instead of anon key for mobile and desktop apps>'}
2525
`}
2626
</SimpleCodeBlock>
2727
</ConnectTabContent>
@@ -31,17 +31,18 @@ EXPO_PUBLIC_SUPABASE_ANON_KEY=${projectKeys.anonKey ?? 'your-anon-key'}
3131
{`
3232
import 'react-native-url-polyfill/auto'
3333
import AsyncStorage from '@react-native-async-storage/async-storage'
34-
import { createClient } from '@supabase/supabase-js'
34+
import { createClient, processLock } from '@supabase/supabase-js'
3535
3636
export const supabase = createClient(
37-
process.env.EXPO_PUBLIC_SUPABASE_URL || "",
38-
process.env.EXPO_PUBLIC_SUPABASE_ANON_KEY || "",
37+
process.env.EXPO_PUBLIC_SUPABASE_URL!,
38+
process.env.EXPO_PUBLIC_SUPABASE_KEY!,
3939
{
4040
auth: {
4141
storage: AsyncStorage,
4242
autoRefreshToken: true,
4343
persistSession: true,
4444
detectSessionInUrl: false,
45+
lock: processLock,
4546
},
4647
})
4748
`}

apps/studio/components/interfaces/Connect/content/flutter/supabaseflutter/content.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ import 'package:supabase_flutter/supabase_flutter.dart';
2424
Future<void> main() async {
2525
await Supabase.initialize(
2626
url: '${projectKeys.apiUrl ?? 'your-project-url'}',
27-
anonKey: '${projectKeys.anonKey ?? 'your-anon-key'}',
27+
anonKey: '${projectKeys.publishableKey ?? '<prefer publishable key instead of anon key for mobile and desktop apps>'}',
2828
);
2929
runApp(MyApp());
3030
}

apps/studio/components/interfaces/Connect/content/ionicangular/supabasejs/content.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ const ContentFile = ({ projectKeys }: ContentFileProps) => {
2424
{`
2525
export const environment = {
2626
supabaseUrl: '${projectKeys.apiUrl ?? 'your-project-url'}',
27-
supabaseKey: '${projectKeys.anonKey ?? 'your-anon-key'}',
27+
supabaseKey: '${projectKeys.publishableKey ?? '<prefer publishabke key instead of anon key for mobile apps>'}',
2828
};
2929
`}
3030
</SimpleCodeBlock>

apps/studio/components/interfaces/Connect/content/ionicreact/supabasejs/content.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ const ContentFile = ({ projectKeys }: ContentFileProps) => {
2121
<SimpleCodeBlock className="bash" parentClassName="min-h-72">
2222
{`
2323
REACT_APP_SUPABASE_URL=${projectKeys.apiUrl ?? 'your-project-url'}
24-
REACT_APP_SUPABASE_ANON_KEY=${projectKeys.anonKey ?? 'your-anon-key'}
24+
REACT_APP_SUPABASE_KEY=${projectKeys.publishableKey ?? '<prefer publishable key instead of anon key for mobile or desktop apps>'}
2525
`}
2626
</SimpleCodeBlock>
2727
</ConnectTabContent>
@@ -32,7 +32,7 @@ REACT_APP_SUPABASE_ANON_KEY=${projectKeys.anonKey ?? 'your-anon-key'}
3232
import { createClient } from '@supabase/supabase-js'
3333
3434
const supabaseUrl = process.env.REACT_APP_SUPABASE_URL
35-
const supabaseAnonKey = process.env.REACT_APP_SUPABASE_ANON_KEY
35+
const supabaseKey = process.env.REACT_APP_SUPABASE_KEY
3636
3737
export const supabase = createClient(supabaseUrl, supabaseAnonKey)
3838
`}

apps/studio/components/interfaces/Connect/content/nextjs/app/supabasejs/content.tsx

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,14 @@ const ContentFile = ({ projectKeys }: ContentFileProps) => {
2121

2222
<ConnectTabContent value=".env.local">
2323
<SimpleCodeBlock className="bash" parentClassName="min-h-72">
24-
{`
25-
NEXT_PUBLIC_SUPABASE_URL=${projectKeys.apiUrl ?? 'your-project-url'}
26-
NEXT_PUBLIC_SUPABASE_ANON_KEY=${projectKeys.anonKey ?? 'your-anon-key'}
27-
`}
24+
{[
25+
'',
26+
`NEXT_PUBLIC_SUPABASE_URL=${projectKeys.apiUrl ?? 'your-project-url'}`,
27+
projectKeys?.publishableKey
28+
? `NEXT_PUBLIC_SUPABASE_PUBLISHABLE_DEFAULT_KEY=${projectKeys.publishableKey}`
29+
: `NEXT_PUBLIC_SUPABASE_ANON_KEY=${projectKeys.anonKey ?? 'your-anon-key'}`,
30+
'',
31+
].join('\n')}
2832
</SimpleCodeBlock>
2933
</ConnectTabContent>
3034

@@ -58,10 +62,13 @@ export default async function Page() {
5862
import { createServerClient, type CookieOptions } from "@supabase/ssr";
5963
import { cookies } from "next/headers";
6064
65+
const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL;
66+
const supabaseKey = process.env.${projectKeys?.publishableKey ? 'NEXT_PUBLIC_SUPABASE_PUBLISHABLE_DEFAULT_KEY' : 'NEXT_PUBLIC_SUPABASE_ANON_KEY'};
67+
6168
export const createClient = (cookieStore: ReturnType<typeof cookies>) => {
6269
return createServerClient(
63-
process.env.NEXT_PUBLIC_SUPABASE_URL!,
64-
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
70+
supabaseUrl!,
71+
supabaseKey!,
6572
{
6673
cookies: {
6774
getAll() {
@@ -88,10 +95,13 @@ export const createClient = (cookieStore: ReturnType<typeof cookies>) => {
8895
{`
8996
import { createBrowserClient } from "@supabase/ssr";
9097
98+
const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL;
99+
const supabaseKey = process.env.${projectKeys?.publishableKey ? 'NEXT_PUBLIC_SUPABASE_PUBLISHABLE_DEFAULT_KEY' : 'NEXT_PUBLIC_SUPABASE_ANON_KEY'};
100+
91101
export const createClient = () =>
92102
createBrowserClient(
93-
process.env.NEXT_PUBLIC_SUPABASE_URL!,
94-
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
103+
supabaseUrl!,
104+
supabaseKey!,
95105
);
96106
`}
97107
</SimpleCodeBlock>
@@ -103,6 +113,9 @@ export const createClient = () =>
103113
import { createServerClient, type CookieOptions } from "@supabase/ssr";
104114
import { type NextRequest, NextResponse } from "next/server";
105115
116+
const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL;
117+
const supabaseKey = process.env.${projectKeys?.publishableKey ? 'NEXT_PUBLIC_SUPABASE_PUBLISHABLE_DEFAULT_KEY' : 'NEXT_PUBLIC_SUPABASE_ANON_KEY'};
118+
106119
export const createClient = (request: NextRequest) => {
107120
// Create an unmodified response
108121
let supabaseResponse = NextResponse.next({
@@ -112,8 +125,8 @@ export const createClient = (request: NextRequest) => {
112125
});
113126
114127
const supabase = createServerClient(
115-
process.env.NEXT_PUBLIC_SUPABASE_URL!,
116-
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
128+
supabaseUrl!,
129+
supabaseKey!,
117130
{
118131
cookies: {
119132
getAll() {
@@ -134,7 +147,6 @@ export const createClient = (request: NextRequest) => {
134147
135148
return supabaseResponse
136149
};
137-
138150
`}
139151
</SimpleCodeBlock>
140152
</ConnectTabContent>

apps/studio/components/interfaces/Connect/content/nextjs/pages/supabasejs/content.tsx

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,14 @@ const ContentFile = ({ projectKeys }: ContentFileProps) => {
1919

2020
<ConnectTabContent value=".env.local">
2121
<SimpleCodeBlock className="bash" parentClassName="min-h-72">
22-
{`
23-
NEXT_PUBLIC_SUPABASE_URL=${projectKeys.apiUrl ?? 'your-project-url'}
24-
NEXT_PUBLIC_SUPABASE_ANON_KEY=${projectKeys.anonKey ?? 'your-anon-key'}
25-
`}
22+
{[
23+
'',
24+
`NEXT_PUBLIC_SUPABASE_URL=${projectKeys.apiUrl ?? 'your-project-url'}`,
25+
projectKeys?.publishableKey
26+
? `NEXT_PUBLIC_SUPABASE_PUBLISHABLE_DEFAULT_KEY=${projectKeys.publishableKey}`
27+
: `NEXT_PUBLIC_SUPABASE_ANON_KEY=${projectKeys.anonKey ?? 'your-anon-key'}`,
28+
'',
29+
].join('\n')}
2630
</SimpleCodeBlock>
2731
</ConnectTabContent>
2832

@@ -32,7 +36,7 @@ NEXT_PUBLIC_SUPABASE_ANON_KEY=${projectKeys.anonKey ?? 'your-anon-key'}
3236
import { createClient } from "@supabase/supabase-js";
3337
3438
const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL;
35-
const supabaseKey = process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY;
39+
const supabaseKey = process.env.${projectKeys?.publishableKey ? 'NEXT_PUBLIC_SUPABASE_PUBLISHABLE_DEFAULT_KEY' : 'NEXT_PUBLIC_SUPABASE_ANON_KEY'};
3640
3741
export const supabase = createClient(supabaseUrl, supabaseKey);
3842
`}

0 commit comments

Comments
 (0)