Skip to content

Commit d97aba9

Browse files
committed
reset password
1 parent f766a3b commit d97aba9

File tree

11 files changed

+247
-50
lines changed

11 files changed

+247
-50
lines changed
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
import { DeleteObjectCommand, S3Client } from '@aws-sdk/client-s3'
2+
import { NextRequest, NextResponse } from 'next/server'
3+
import { createClient } from '~/utils/supabase/server'
4+
5+
const s3Client = new S3Client({ endpoint: process.env.S3_ENDPOINT, forcePathStyle: true })
6+
7+
export type DatabaseDeleteResponse =
8+
| {
9+
success: true
10+
}
11+
| {
12+
success: false
13+
error: string
14+
}
15+
16+
export async function DELETE(
17+
_req: NextRequest,
18+
{ params }: { params: { id: string } }
19+
): Promise<NextResponse<DatabaseDeleteResponse>> {
20+
const supabase = createClient()
21+
22+
const {
23+
data: { user },
24+
} = await supabase.auth.getUser()
25+
26+
if (!user) {
27+
return NextResponse.json(
28+
{
29+
success: false,
30+
error: 'Unauthorized',
31+
},
32+
{ status: 401 }
33+
)
34+
}
35+
36+
const databaseId = params.id
37+
38+
const { data: existingDeployedDatabase } = await supabase
39+
.from('deployed_databases')
40+
.select('id')
41+
.eq('database_id', databaseId)
42+
.maybeSingle()
43+
44+
if (!existingDeployedDatabase) {
45+
return NextResponse.json(
46+
{
47+
success: false,
48+
error: `Database ${databaseId} was not found`,
49+
},
50+
{ status: 404 }
51+
)
52+
}
53+
54+
await supabase.from('deployed_databases').delete().eq('database_id', databaseId)
55+
56+
const key = `dbs/${databaseId}.tar.gz`
57+
try {
58+
await s3Client.send(
59+
new DeleteObjectCommand({
60+
Bucket: process.env.S3_BUCKET,
61+
Key: key,
62+
})
63+
)
64+
} catch (error) {
65+
console.error(`Error deleting S3 object ${key}:`, error)
66+
}
67+
68+
return NextResponse.json({
69+
success: true,
70+
})
71+
}

apps/postgres-new/components/sidebar/database-list/database-item/database-item-actions/database-item-deploy-action.tsx

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
import { Loader, Upload } from 'lucide-react'
2-
import Link from 'next/link'
32
import { useState } from 'react'
43
import { useApp } from '~/components/app-provider'
5-
import { CodeBlock } from '~/components/code-block'
64
import { DeployedDatabaseFields } from '~/components/deployed-database-fields'
75
import {
86
Dialog,
@@ -17,7 +15,6 @@ import {
1715
DeployedDatabaseCreateResult,
1816
useDeployedDatabaseCreateMutation,
1917
} from '~/data/deployed-databases/deployed-database-create-mutation'
20-
import { LocalDatabase } from '~/lib/db'
2118

2219
export type DatabaseItemDeployActionProps = {
2320
database: Database
@@ -122,11 +119,13 @@ function DatabaseItemDeployActionDialog(props: DatabaseItemDeployActionDialogPro
122119
</p>
123120
<DeployedDatabaseFields {...props} />
124121
{props.password && (
125-
<p className="text-sm text-muted-foreground">
126-
Please{' '}
127-
<span className="font-bold text-destructive-foreground">save your password</span>, it
128-
will not be shown again!
129-
</p>
122+
<div className="flex justify-center pt-2">
123+
<p className="text-sm text-muted-foreground">
124+
Please{' '}
125+
<span className="font-bold text-destructive-foreground">save your password</span>,
126+
it will not be shown again!
127+
</p>
128+
</div>
130129
)}
131130
</DialogContent>
132131
</DialogPortal>

apps/postgres-new/components/sidebar/database-list/database-item/deployed-database-dialog.tsx

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
1+
import { Loader, LoaderIcon, RefreshCwIcon } from 'lucide-react'
2+
import { useState } from 'react'
13
import {
24
DeployedDatabaseFields,
35
DeployedDatabaseFieldsProps,
46
} from '~/components/deployed-database-fields'
7+
import { Button } from '~/components/ui/button'
58
import {
69
Dialog,
710
DialogContent,
@@ -11,20 +14,32 @@ import {
1114
DialogTrigger,
1215
} from '~/components/ui/dialog'
1316
import { Database } from '~/data/databases/database-type'
17+
import { useDeployedDatabaseResetPasswordMutation } from '~/data/deployed-databases/deployed-database-reset-password-mutation'
1418

1519
type DeployedDatabaseDialogProps = {
1620
database: Database
1721
children: React.ReactNode
1822
}
1923

2024
export function DeployedDatabaseDialog(props: DeployedDatabaseDialogProps) {
25+
const [password, setPassword] = useState<string | undefined>()
26+
const { mutateAsync: resetDatabasePassword, isPending: isResettingDatabasePassword } =
27+
useDeployedDatabaseResetPasswordMutation()
28+
2129
// TODO: maybe store these infos as part of the Database type
2230
const fields: DeployedDatabaseFieldsProps = {
2331
username: 'readonly_postgres',
2432
databaseName: 'postgres',
2533
host: `${props.database.id}.${process.env.NEXT_PUBLIC_WILDCARD_DOMAIN}`,
2634
port: 5432,
35+
password,
36+
}
37+
38+
async function handleResetPassword() {
39+
const result = await resetDatabasePassword({ databaseId: props.database.id })
40+
setPassword(result.password)
2741
}
42+
2843
return (
2944
<Dialog>
3045
<DialogTrigger>{props.children}</DialogTrigger>
@@ -47,6 +62,36 @@ export function DeployedDatabaseDialog(props: DeployedDatabaseDialogProps) {
4762
instance so that it can be accessed outside the browser using any Postgres client.
4863
</p>
4964
<DeployedDatabaseFields {...fields} />
65+
<div className="flex justify-center pt-2">
66+
{password ? (
67+
<p className="text-sm text-muted-foreground">
68+
Please{' '}
69+
<span className="font-bold text-destructive-foreground">save your password</span>,
70+
it will not be shown again!
71+
</p>
72+
) : (
73+
<p className="text-sm text-muted-foreground flex place-items-center">
74+
<span className="mr-2">Forgot your database password?</span>
75+
<Button
76+
className="text-foreground h-6"
77+
variant="outline"
78+
onClick={handleResetPassword}
79+
size="sm"
80+
>
81+
{isResettingDatabasePassword ? (
82+
<Loader
83+
className="mr-1 animate-spin flex-shrink-0 text-muted-foreground"
84+
size={12}
85+
strokeWidth={2}
86+
/>
87+
) : (
88+
<RefreshCwIcon className="h-3 w-3 mr-1 text-muted-foreground" />
89+
)}
90+
Generate a new password
91+
</Button>
92+
</p>
93+
)}
94+
</div>
5095
</DialogContent>
5196
</DialogPortal>
5297
</Dialog>

apps/postgres-new/data/deployed-databases/deployed-database-create-mutation.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import { useMutation, UseMutationOptions, useQueryClient } from '@tanstack/react-query'
2-
import { createClient } from '~/utils/supabase/client'
32
import { getDeployedDatabasesQueryKey } from './deployed-databases-query'
43
import { useApp } from '~/components/app-provider'
54
import type { DatabaseUploadResponse } from '~/app/api/databases/[id]/upload/route'
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import { useMutation, UseMutationOptions, useQueryClient } from '@tanstack/react-query'
2+
import { getDeployedDatabasesQueryKey } from './deployed-databases-query'
3+
import type { DatabaseDeleteResponse } from '~/app/api/databases/[id]/route'
4+
5+
export type DeployedDatabaseDeleteVariables = {
6+
databaseId: string
7+
}
8+
9+
export const useDeployedDatabaseDeleteMutation = ({
10+
onSuccess,
11+
onError,
12+
...options
13+
}: Omit<UseMutationOptions<void, Error, DeployedDatabaseDeleteVariables>, 'mutationFn'> = {}) => {
14+
const queryClient = useQueryClient()
15+
16+
return useMutation<void, Error, DeployedDatabaseDeleteVariables>({
17+
mutationFn: async (variables) => {
18+
const response = await fetch(`/api/databases/${variables.databaseId}`, {
19+
method: 'DELETE',
20+
})
21+
22+
const result = (await response.json()) as DatabaseDeleteResponse
23+
24+
if (!result.success) {
25+
throw new Error(result.error)
26+
}
27+
},
28+
async onSuccess(data, variables, context) {
29+
await Promise.all([
30+
queryClient.invalidateQueries({ queryKey: getDeployedDatabasesQueryKey() }),
31+
])
32+
return onSuccess?.(data, variables, context)
33+
},
34+
...options,
35+
})
36+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import { useMutation, UseMutationOptions, useQueryClient } from '@tanstack/react-query'
2+
import { getDeployedDatabasesQueryKey } from './deployed-databases-query'
3+
import { DatabaseResetPasswordResponse } from '~/app/api/databases/[id]/reset-password/route'
4+
5+
export type DeployedDatabaseResetPasswordVariables = {
6+
databaseId: string
7+
}
8+
9+
export type DeployedDatabaseResetPasswordResult = Extract<
10+
DatabaseResetPasswordResponse,
11+
{ success: true }
12+
>['data']
13+
14+
export const useDeployedDatabaseResetPasswordMutation = ({
15+
onSuccess,
16+
onError,
17+
...options
18+
}: Omit<
19+
UseMutationOptions<
20+
DeployedDatabaseResetPasswordResult,
21+
Error,
22+
DeployedDatabaseResetPasswordVariables
23+
>,
24+
'mutationFn'
25+
> = {}) => {
26+
const queryClient = useQueryClient()
27+
28+
return useMutation<
29+
DeployedDatabaseResetPasswordResult,
30+
Error,
31+
DeployedDatabaseResetPasswordVariables
32+
>({
33+
mutationFn: async (variables) => {
34+
const response = await fetch(`/api/databases/${variables.databaseId}/reset-password`, {
35+
method: 'POST',
36+
})
37+
38+
const result = (await response.json()) as DatabaseResetPasswordResponse
39+
40+
if (!result.success) {
41+
throw new Error(result.error)
42+
}
43+
44+
return result.data
45+
},
46+
async onSuccess(data, variables, context) {
47+
await Promise.all([
48+
queryClient.invalidateQueries({ queryKey: getDeployedDatabasesQueryKey() }),
49+
])
50+
return onSuccess?.(data, variables, context)
51+
},
52+
...options,
53+
})
54+
}

apps/postgres-new/utils/supabase/db-types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ export type Database = {
7474
Insert: {
7575
auth_data?: Json | null
7676
auth_method: string
77-
created_at?: string
77+
created_at: string
7878
database_id: string
7979
deployed_at?: string
8080
id?: never

supabase/migrations/20240808125852_deployed_databases.sql

Lines changed: 0 additions & 36 deletions
This file was deleted.

supabase/migrations/20240813082019_add_name_column_to_deployed_databases.sql

Lines changed: 0 additions & 1 deletion
This file was deleted.

supabase/migrations/20240813123112_rename_created_at.sql

Lines changed: 0 additions & 3 deletions
This file was deleted.

0 commit comments

Comments
 (0)