Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ const onSubmit = (e: Event) => {

const query = new URLSearchParams({ query: inputRef.current!.value })
const projectUrl = `https://your-project-ref.supabase.co/functions/v1`
const queryURL = `${projectURL}/${query}`
const queryURL = `${projectUrl}/${query}`
const eventSource = new EventSource(queryURL)

eventSource.addEventListener("error", (err) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ as $$
(
user_id,
factor_id,
last_refreshed_at
last_failed_at
)
values
(
Expand All @@ -151,7 +151,7 @@ as $$
now()
)
on conflict do update
set last_refreshed_at = now();
set last_failed_at = now();

-- finally let Supabase Auth do the default behavior for a failed attempt
return jsonb_build_object('decision', 'continue');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ create table instruments (
name text
);

insert into books
insert into instruments
(id, name)
values
(1, 'violin'),
Expand Down
4 changes: 2 additions & 2 deletions apps/docs/content/guides/database/drizzle.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,8 @@ If you plan on solely using Drizzle instead of the Supabase Data API (PostgREST)
import postgres from 'postgres'

let connectionString = process.env.DATABASE_URL
if (host.includes('postgres:postgres@supabase_db_')) {
const url = URL.parse(host)!
if (connectionString.includes('postgres:postgres@supabase_db_')) {
const url = URL.parse(connectionString)!
url.hostname = url.hostname.split('_')[1]
connectionString = url.href
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ explain select * from book;
(1 row)
```

Now we can choose a `statement_cost_filter` value between the total cost for the single select (2.49) and the whole table select (135.0) so one statement will succeed and one will fail.
Now we can choose a `statement_cost_limit` value between the total cost for the single select (2.49) and the whole table select (135.0) so one statement will succeed and one will fail.

{/* prettier-ignore */}
```sql
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ supabase migration new create_posts_table
user_id text,
title text,
content text,
created_at timestamptz default now()
created_at timestamptz default now(),
updated_at timestamptz default now()
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ WHERE id IN (

This approach has the benefit of controlling when it runs, locking for a shorter period of time and minimising impact on other transactions.

If you know in advance that such large deletes will have to happen in the business cycle of your database, then you should seriously think about using (table parititioning)[/docs/guides/database/partitions] as a management tool.
If you know in advance that such large deletes will have to happen in the business cycle of your database, then you should seriously think about using [table partitioning](/docs/guides/database/partitions) as a management tool.

### Soft deletes

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,9 @@ select distinct
points
from
seasons
order BY
id,
points desc,
team;
order by
team,
points desc;
```

The important bits here are:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ hideToc: true
<StepHikeCompact.Details title="Update seed script">
Let's seed the database with a few instruments.

Update the file `scripts/seeds.ts` to contain the following code:
Update the file `scripts/seed.ts` to contain the following code:
</StepHikeCompact.Details>

<StepHikeCompact.Code>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ Add `CFBundleURLTypes` to enable deep linking:

<$CodeTabs>

```xml name=ios/Runner/Info.plist"
```xml name=ios/Runner/Info.plist
<!-- ... other tags -->
<plist>
<dict>
Expand Down Expand Up @@ -314,7 +314,7 @@ Let's create a new widget called `account_page.dart` for that.

<$CodeTabs>

```dart name=lib/pages/account_page.dart"
```dart name=lib/pages/account_page.dart
import 'package:flutter/material.dart';
import 'package:supabase_flutter/supabase_flutter.dart';
import 'package:supabase_quickstart/main.dart';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ description: 'Using the CLI to test your Supabase project.'
subtitle: 'Using the CLI to test your Supabase project.'
---

The Supabase CLI provides a set of tools to help you test and lint your Postgres database and Edge` Functions.
The Supabase CLI provides a set of tools to help you test and lint your Postgres database and Edge Functions.

## Testing your database

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ regexp_contains(event_message, '^connection')

```sql
-- find only messages that ends with port=12345
regexp_contains(event_message, '$port=12345')
regexp_contains(event_message, 'port=12345$')
```

### Ignore case sensitivity:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,8 @@ export function ConnectStepsSection({ steps, state, projectKeys }: ConnectStepsS
!ipv4Addon &&
(state.connectionMethod === 'direct' ||
(state.connectionMethod === 'transaction' && !state.useSharedPooler))
const showSessionPoolerNotice =
deploymentMode.isPlatform && state.mode === 'direct' && state.connectionMethod === 'session'

const showSelfHostedMcpNotice = deploymentMode.isSelfHosted && state.mode === 'mcp'

Expand All @@ -200,8 +202,6 @@ export function ConnectStepsSection({ steps, state, projectKeys }: ConnectStepsS
<div className="p-8 flex flex-col gap-y-6">
<h3>Connect your app</h3>

<CopyPromptAdmonition stepsContainerRef={stepsContainerRef} />

{showIpv4AddonNotice && (
<Admonition
type="default"
Expand All @@ -216,6 +216,14 @@ export function ConnectStepsSection({ steps, state, projectKeys }: ConnectStepsS
/>
)}

{showSessionPoolerNotice && (
<Admonition
type="default"
title="Only use Session Pooler on an IPv4 network"
description="Session pooler connections are IPv4 proxied for free. Use Direct Connection if connecting via an IPv6 network."
/>
)}

{showSelfHostedMcpNotice && (
<Admonition
type="default"
Expand All @@ -230,6 +238,8 @@ export function ConnectStepsSection({ steps, state, projectKeys }: ConnectStepsS
/>
)}

<CopyPromptAdmonition stepsContainerRef={stepsContainerRef} />

<div className="mt-6" ref={stepsContainerRef}>
{steps.map((step, index) => (
<ConnectSheetStep
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { describe, expect, test } from 'vitest'

import {
buildConnectionParameters,
buildConnectionStringWithPassword,
buildSafeConnectionString,
DEFAULT_PORT,
parseConnectionParams,
Expand Down Expand Up @@ -70,6 +71,23 @@ describe('buildSafeConnectionString', () => {
})
})

describe('buildConnectionStringWithPassword', () => {
test('returns the original string when input or password is empty', () => {
const uri = `postgresql://postgres:${PASSWORD_PLACEHOLDER}@localhost:5432/postgres`

expect(buildConnectionStringWithPassword('', 'password')).toBe('')
expect(buildConnectionStringWithPassword(uri, '')).toBe(uri)
})

test('replaces every password placeholder with the encoded password', () => {
const uri = `postgresql://postgres:${PASSWORD_PLACEHOLDER}@localhost:5432/postgres?password=${PASSWORD_PLACEHOLDER}`

expect(buildConnectionStringWithPassword(uri, 'p@ss/word#1')).toBe(
'postgresql://postgres:p%40ss%2Fword%231@localhost:5432/postgres?password=p%40ss%2Fword%231'
)
})
})

describe('resolveConnectionString', () => {
const pooler = {
transactionShared: 'tx-shared',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,23 @@ export const buildSafeConnectionString = (
return `postgresql://${params.user}:${PASSWORD_PLACEHOLDER}@${params.host}:${params.port}/${params.database}${search}`
}

export const buildConnectionStringWithPassword = (
connectionString: string,
password: string
): string => {
if (!connectionString || !password) return connectionString

const encodedPassword = (() => {
try {
return encodeURIComponent(password)
} catch {
return password
}
})()

return connectionString.split(PASSWORD_PLACEHOLDER).join(encodedPassword)
}

export const buildConnectionParameters = (params: ConnectionParams) => [
{ key: 'host', value: params.host },
{ key: 'port', value: params.port },
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { describe, expect, test } from 'vitest'

import { buildConnectPrompt } from './CopyPromptAdmonition'

describe('buildConnectPrompt', () => {
test('uses redacted copy values instead of temporarily visible passwords', () => {
const container = document.createElement('div')
container.innerHTML = `
<div
data-connect-step
data-step-title="Connection string"
data-step-description="Copy the connection details for your database."
>
<div data-step-content>
<div
data-connect-copy-value="postgresql://postgres:[YOUR-PASSWORD]@db.example.supabase.co:5432/postgres"
>
<pre>postgresql://postgres:temporary-password@db.example.supabase.co:5432/postgres</pre>
</div>
</div>
</div>
`

const prompt = buildConnectPrompt(container)

expect(prompt).toContain(
'postgresql://postgres:[YOUR-PASSWORD]@db.example.supabase.co:5432/postgres'
)
expect(prompt).not.toContain('temporary-password')
})
})
Loading
Loading