@plutocms/supabase 0.0.1-alpha.7 → 0.0.1-alpha.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/app/middleware/auth.ts +5 -1
- package/app/pages/admin/setup.vue +163 -23
- package/app/pages/admin.vue +1 -0
- package/package.json +1 -1
- package/public/schema.sql +133 -39
- package/server/api/setup/create.post.ts +23 -8
- package/server/api/signup.post.ts +35 -8
package/app/middleware/auth.ts
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
|
+
import type { RouteLocationNormalizedGeneric } from 'vue-router'
|
|
2
|
+
|
|
1
3
|
export default defineNuxtRouteMiddleware(async (to, from) => {
|
|
2
|
-
const { isLoggedIn, logout } = await useAuth({
|
|
4
|
+
const { isLoggedIn, logout } = await useAuth({
|
|
5
|
+
route: to as RouteLocationNormalizedGeneric,
|
|
6
|
+
})
|
|
3
7
|
|
|
4
8
|
if (
|
|
5
9
|
isLoggedIn.value &&
|
|
@@ -23,10 +23,10 @@ const items = ref<StepperItem[]>([
|
|
|
23
23
|
icon: 'i-lucide-database',
|
|
24
24
|
},
|
|
25
25
|
|
|
26
|
-
|
|
26
|
+
{
|
|
27
27
|
title: 'Admin Account',
|
|
28
28
|
icon: 'i-lucide-user',
|
|
29
|
-
},
|
|
29
|
+
},
|
|
30
30
|
|
|
31
31
|
{
|
|
32
32
|
title: 'Complete Setup',
|
|
@@ -39,17 +39,29 @@ const stepper = useTemplateRef('stepper')
|
|
|
39
39
|
const currentStep = ref<number>(0)
|
|
40
40
|
|
|
41
41
|
const isSettingUpDatabase = ref(false)
|
|
42
|
+
const isCreatingAdmin = ref(false)
|
|
42
43
|
|
|
43
44
|
const databaseForm = ref({
|
|
44
45
|
connectionString: '',
|
|
45
46
|
password: '',
|
|
46
47
|
})
|
|
47
48
|
|
|
49
|
+
const adminForm = ref({
|
|
50
|
+
username: '',
|
|
51
|
+
display_name: '',
|
|
52
|
+
email: '',
|
|
53
|
+
password: '',
|
|
54
|
+
})
|
|
55
|
+
|
|
48
56
|
const currentLoading = computed(() => {
|
|
49
57
|
if (currentStep.value === 0) {
|
|
50
58
|
return isSettingUpDatabase.value
|
|
51
59
|
}
|
|
52
60
|
|
|
61
|
+
if (currentStep.value === 1) {
|
|
62
|
+
return isCreatingAdmin.value
|
|
63
|
+
}
|
|
64
|
+
|
|
53
65
|
return false
|
|
54
66
|
})
|
|
55
67
|
|
|
@@ -58,10 +70,26 @@ const currentStepId = computed(() => {
|
|
|
58
70
|
return 'database-setup-form'
|
|
59
71
|
}
|
|
60
72
|
|
|
73
|
+
if (currentStep.value === 1) {
|
|
74
|
+
return 'admin-setup-form'
|
|
75
|
+
}
|
|
76
|
+
|
|
61
77
|
return undefined
|
|
62
78
|
})
|
|
63
79
|
|
|
64
|
-
|
|
80
|
+
const currentStepSubmitLabel = computed(() => {
|
|
81
|
+
if (currentStep.value === 0) {
|
|
82
|
+
return 'Set up database'
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
if (currentStep.value === 1) {
|
|
86
|
+
return 'Create admin account'
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
return 'Submit'
|
|
90
|
+
})
|
|
91
|
+
|
|
92
|
+
async function completeDatabaseSetup() {
|
|
65
93
|
try {
|
|
66
94
|
isSettingUpDatabase.value = true
|
|
67
95
|
|
|
@@ -73,6 +101,7 @@ async function completeSetup() {
|
|
|
73
101
|
'[YOUR-PASSWORD]',
|
|
74
102
|
encodeURIComponent(databaseForm.value.password)
|
|
75
103
|
),
|
|
104
|
+
adminForm: adminForm.value,
|
|
76
105
|
},
|
|
77
106
|
})
|
|
78
107
|
|
|
@@ -111,9 +140,63 @@ async function completeSetup() {
|
|
|
111
140
|
}
|
|
112
141
|
}
|
|
113
142
|
|
|
143
|
+
async function createAdminAccount() {
|
|
144
|
+
try {
|
|
145
|
+
isCreatingAdmin.value = true
|
|
146
|
+
|
|
147
|
+
const data = await $fetch('/api/signup', {
|
|
148
|
+
method: 'POST',
|
|
149
|
+
body: {
|
|
150
|
+
username: adminForm.value.username,
|
|
151
|
+
display_name: adminForm.value.display_name,
|
|
152
|
+
email: adminForm.value.email,
|
|
153
|
+
password: adminForm.value.password,
|
|
154
|
+
is_admin: true,
|
|
155
|
+
},
|
|
156
|
+
})
|
|
157
|
+
|
|
158
|
+
if (data.success === false) {
|
|
159
|
+
toast.add({
|
|
160
|
+
title: 'Admin account creation failed',
|
|
161
|
+
description: data.message || 'Please try again.',
|
|
162
|
+
icon: 'lucide:circle-x',
|
|
163
|
+
color: 'error',
|
|
164
|
+
})
|
|
165
|
+
|
|
166
|
+
return
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
toast.add({
|
|
170
|
+
title: 'Admin account created',
|
|
171
|
+
description: 'Your admin account has been created successfully.',
|
|
172
|
+
icon: 'lucide:check-circle',
|
|
173
|
+
color: 'success',
|
|
174
|
+
})
|
|
175
|
+
|
|
176
|
+
stepper.value?.next()
|
|
177
|
+
} catch (error) {
|
|
178
|
+
if (import.meta.dev) {
|
|
179
|
+
console.error('Error creating admin account:', error)
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
toast.add({
|
|
183
|
+
title: 'Error creating admin account',
|
|
184
|
+
description: 'Please check the console for more details.',
|
|
185
|
+
icon: 'lucide:circle-x',
|
|
186
|
+
color: 'error',
|
|
187
|
+
})
|
|
188
|
+
} finally {
|
|
189
|
+
isCreatingAdmin.value = false
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
114
193
|
function handleStepChange(step: number) {
|
|
194
|
+
if (step === 0) {
|
|
195
|
+
completeDatabaseSetup()
|
|
196
|
+
}
|
|
197
|
+
|
|
115
198
|
if (step === 1) {
|
|
116
|
-
|
|
199
|
+
createAdminAccount()
|
|
117
200
|
}
|
|
118
201
|
}
|
|
119
202
|
</script>
|
|
@@ -123,20 +206,14 @@ function handleStepChange(step: number) {
|
|
|
123
206
|
<div class="flex justify-center items-center h-screen">
|
|
124
207
|
<UCard class="w-[500px]">
|
|
125
208
|
<div class="flex flex-col gap-y-8">
|
|
126
|
-
<UStepper
|
|
127
|
-
ref="stepper"
|
|
128
|
-
v-model="currentStep"
|
|
129
|
-
:items="items"
|
|
130
|
-
disabled
|
|
131
|
-
linear
|
|
132
|
-
/>
|
|
209
|
+
<UStepper ref="stepper" v-model="currentStep" :items="items" linear />
|
|
133
210
|
|
|
134
211
|
<div>
|
|
135
212
|
<section v-if="currentStep === 0">
|
|
136
213
|
<UForm
|
|
137
214
|
id="database-setup-form"
|
|
138
215
|
class="flex flex-col gap-y-4"
|
|
139
|
-
@submit="handleStepChange(currentStep
|
|
216
|
+
@submit="handleStepChange(currentStep)"
|
|
140
217
|
>
|
|
141
218
|
<UFormField label="Supabase connection string" required>
|
|
142
219
|
<UInput
|
|
@@ -259,21 +336,85 @@ function handleStepChange(step: number) {
|
|
|
259
336
|
</UForm>
|
|
260
337
|
</section>
|
|
261
338
|
|
|
262
|
-
<section v-
|
|
339
|
+
<section v-if="currentStep === 1">
|
|
340
|
+
<UForm
|
|
341
|
+
id="admin-setup-form"
|
|
342
|
+
class="grid grid-cols-2 gap-4"
|
|
343
|
+
@submit="handleStepChange(currentStep)"
|
|
344
|
+
>
|
|
345
|
+
<UFormField label="Email" class="col-span-2" required>
|
|
346
|
+
<UInput
|
|
347
|
+
v-model="adminForm.email"
|
|
348
|
+
:disabled="isCreatingAdmin"
|
|
349
|
+
placeholder="you@example.com"
|
|
350
|
+
autofocus
|
|
351
|
+
required
|
|
352
|
+
/>
|
|
353
|
+
</UFormField>
|
|
354
|
+
|
|
355
|
+
<UFormField label="Username" required>
|
|
356
|
+
<UInput
|
|
357
|
+
v-model="adminForm.username"
|
|
358
|
+
:disabled="isCreatingAdmin"
|
|
359
|
+
placeholder="Username"
|
|
360
|
+
required
|
|
361
|
+
/>
|
|
362
|
+
</UFormField>
|
|
363
|
+
|
|
364
|
+
<UFormField label="Display Name" required>
|
|
365
|
+
<UInput
|
|
366
|
+
v-model="adminForm.display_name"
|
|
367
|
+
:disabled="isCreatingAdmin"
|
|
368
|
+
placeholder="Display Name"
|
|
369
|
+
required
|
|
370
|
+
/>
|
|
371
|
+
</UFormField>
|
|
372
|
+
|
|
373
|
+
<UFormField label="Password" class="col-span-2" required>
|
|
374
|
+
<UInput
|
|
375
|
+
v-model="adminForm.password"
|
|
376
|
+
:disabled="isCreatingAdmin"
|
|
377
|
+
type="password"
|
|
378
|
+
placeholder="• • • • "
|
|
379
|
+
required
|
|
380
|
+
/>
|
|
381
|
+
</UFormField>
|
|
382
|
+
</UForm>
|
|
383
|
+
</section>
|
|
384
|
+
|
|
385
|
+
<section v-else-if="currentStep === 2">
|
|
263
386
|
<div class="flex flex-col gap-y-4">
|
|
264
|
-
<
|
|
265
|
-
|
|
266
|
-
</h1>
|
|
387
|
+
<hgroup class="text-center">
|
|
388
|
+
<span class="text-3xl">🎉</span>
|
|
267
389
|
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
390
|
+
<h1 class="font-bold text-2xl">Setup Complete</h1>
|
|
391
|
+
</hgroup>
|
|
392
|
+
|
|
393
|
+
<p class="text-balance text-center text-lg">
|
|
394
|
+
Your database is ready and your admin account has been
|
|
395
|
+
created.
|
|
271
396
|
</p>
|
|
272
397
|
|
|
398
|
+
<UAlert icon="lucide:info" color="warning" variant="outline">
|
|
399
|
+
<template #description>
|
|
400
|
+
<p>
|
|
401
|
+
You need to confirm your email address before you can log
|
|
402
|
+
in. Please check your inbox and click on the confirmation
|
|
403
|
+
link. If you don't see the email, please check your spam
|
|
404
|
+
folder.
|
|
405
|
+
</p>
|
|
406
|
+
</template>
|
|
407
|
+
</UAlert>
|
|
408
|
+
|
|
273
409
|
<p class="text-center">
|
|
274
|
-
<
|
|
275
|
-
|
|
410
|
+
<UButton
|
|
411
|
+
icon="lucide:arrow-right"
|
|
412
|
+
to="/admin/login"
|
|
413
|
+
color="primary"
|
|
414
|
+
trailing
|
|
276
415
|
>
|
|
416
|
+
Go to login page
|
|
417
|
+
</UButton>
|
|
277
418
|
</p>
|
|
278
419
|
</div>
|
|
279
420
|
</section>
|
|
@@ -286,10 +427,9 @@ function handleStepChange(step: number) {
|
|
|
286
427
|
:form="currentStepId"
|
|
287
428
|
:loading="currentLoading"
|
|
288
429
|
leading-icon="lucide:check"
|
|
289
|
-
trailing-icon="lucide:arrow-right"
|
|
290
430
|
type="submit"
|
|
291
431
|
>
|
|
292
|
-
|
|
432
|
+
{{ currentStepSubmitLabel }}
|
|
293
433
|
</UButton>
|
|
294
434
|
</div>
|
|
295
435
|
</div>
|
package/app/pages/admin.vue
CHANGED
|
@@ -14,6 +14,7 @@ watch(visibility, async (current, previous) => {
|
|
|
14
14
|
if (current === 'visible' && previous === 'hidden') {
|
|
15
15
|
if (
|
|
16
16
|
!isLoggedIn.value &&
|
|
17
|
+
!route.path.startsWith('/admin/setup') &&
|
|
17
18
|
route.path.startsWith('/admin/') &&
|
|
18
19
|
route.path !== '/admin/login' &&
|
|
19
20
|
route.path !== '/admin/signup'
|
package/package.json
CHANGED
package/public/schema.sql
CHANGED
|
@@ -1,14 +1,20 @@
|
|
|
1
1
|
-- Supabase Schema SQL
|
|
2
2
|
-- Settings
|
|
3
3
|
--- Create enum type for settings
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
'
|
|
7
|
-
|
|
8
|
-
|
|
4
|
+
do $$
|
|
5
|
+
begin
|
|
6
|
+
if not exists (select 1 from pg_type where typname = 'tsettings') then
|
|
7
|
+
create type TSettings as enum (
|
|
8
|
+
'website_title',
|
|
9
|
+
'website_url',
|
|
10
|
+
'website_description'
|
|
11
|
+
);
|
|
12
|
+
end if;
|
|
13
|
+
end
|
|
14
|
+
$$;
|
|
9
15
|
|
|
10
16
|
--- Create settings table
|
|
11
|
-
create table public.settings (
|
|
17
|
+
create table if not exists public.settings (
|
|
12
18
|
id bigint generated by default as identity not null,
|
|
13
19
|
setting_name public.TSettings not null,
|
|
14
20
|
setting_value text not null,
|
|
@@ -20,72 +26,160 @@ create table public.settings (
|
|
|
20
26
|
insert into public.settings (setting_name, setting_value) values
|
|
21
27
|
('website_title', 'My Website'),
|
|
22
28
|
('website_url', 'https://mywebsite.test'),
|
|
23
|
-
('website_description', 'This is my website.')
|
|
29
|
+
('website_description', 'This is my website.')
|
|
30
|
+
on conflict (setting_name) do nothing;
|
|
24
31
|
|
|
25
32
|
alter table public.settings enable row level security;
|
|
26
33
|
|
|
27
34
|
-- Policies for settings table
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
35
|
+
do $$
|
|
36
|
+
begin
|
|
37
|
+
if not exists (
|
|
38
|
+
select 1 from pg_policies where tablename = 'settings' and policyname = 'Enable insert for authenticated users only'
|
|
39
|
+
) then
|
|
40
|
+
create policy "Enable insert for authenticated users only"
|
|
41
|
+
on public.settings
|
|
42
|
+
for insert
|
|
43
|
+
to authenticated, dashboard_user
|
|
44
|
+
with check (true);
|
|
45
|
+
end if;
|
|
46
|
+
end
|
|
47
|
+
$$;
|
|
48
|
+
|
|
49
|
+
do $$
|
|
50
|
+
begin
|
|
51
|
+
if not exists (
|
|
52
|
+
select 1 from pg_policies where tablename = 'settings' and policyname = 'Enable read access for authenticated users on settings'
|
|
53
|
+
) then
|
|
54
|
+
create policy "Enable read access for authenticated users on settings"
|
|
55
|
+
on public.settings
|
|
56
|
+
for select
|
|
57
|
+
to authenticated, dashboard_user
|
|
58
|
+
using (true);
|
|
59
|
+
end if;
|
|
60
|
+
end
|
|
61
|
+
$$;
|
|
62
|
+
|
|
63
|
+
do $$
|
|
64
|
+
begin
|
|
65
|
+
if not exists (
|
|
66
|
+
select 1 from pg_policies where tablename = 'settings' and policyname = 'Enable update for authenticated users on settings'
|
|
67
|
+
) then
|
|
68
|
+
create policy "Enable update for authenticated users on settings"
|
|
69
|
+
on public.settings
|
|
70
|
+
for update
|
|
71
|
+
to authenticated, dashboard_user
|
|
72
|
+
using (true)
|
|
73
|
+
with check (true);
|
|
74
|
+
end if;
|
|
75
|
+
end
|
|
76
|
+
$$;
|
|
32
77
|
|
|
33
78
|
--- Create enum type for healthcheck names
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
)
|
|
79
|
+
do $$
|
|
80
|
+
begin
|
|
81
|
+
if not exists (select 1 from pg_type where typname = 'thealthcheck') then
|
|
82
|
+
create type THealthcheck as enum (
|
|
83
|
+
'first_setup'
|
|
84
|
+
);
|
|
85
|
+
end if;
|
|
86
|
+
end
|
|
87
|
+
$$;
|
|
37
88
|
|
|
38
89
|
--- Create healthcheck table (name/value format like settings)
|
|
39
|
-
create table public.healthcheck (
|
|
90
|
+
create table if not exists public.healthcheck (
|
|
40
91
|
id bigint generated by default as identity not null,
|
|
41
|
-
|
|
42
|
-
|
|
92
|
+
config_name public.THealthcheck not null,
|
|
93
|
+
config_value text not null,
|
|
43
94
|
constraint healthcheck_pkey primary key (id),
|
|
44
|
-
constraint
|
|
95
|
+
constraint healthcheck_config_name_key unique (config_name)
|
|
45
96
|
) TABLESPACE pg_default;
|
|
46
97
|
|
|
47
98
|
--- Insert default healthcheck values
|
|
48
|
-
insert into public.healthcheck (
|
|
49
|
-
('first_setup', 'true')
|
|
99
|
+
insert into public.healthcheck (config_name, config_value) values
|
|
100
|
+
('first_setup', 'true')
|
|
101
|
+
on conflict (config_name) do nothing;
|
|
50
102
|
|
|
51
103
|
alter table public.healthcheck enable row level security;
|
|
52
104
|
|
|
53
105
|
-- Allow read access to healthcheck for public and dashboard_user (no login required)
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
to public
|
|
58
|
-
|
|
106
|
+
do $$
|
|
107
|
+
begin
|
|
108
|
+
if not exists (
|
|
109
|
+
select 1 from pg_policies where tablename = 'healthcheck' and policyname = 'Enable read access for healthcheck to public and dashboard_user'
|
|
110
|
+
) then
|
|
111
|
+
create policy "Enable read access for healthcheck to public and dashboard_user"
|
|
112
|
+
on public.healthcheck
|
|
113
|
+
for select
|
|
114
|
+
to public, dashboard_user
|
|
115
|
+
using (true);
|
|
116
|
+
end if;
|
|
117
|
+
end
|
|
118
|
+
$$;
|
|
119
|
+
|
|
120
|
+
-- Allow update access to healthcheck for authenticated users and dashboard_user
|
|
121
|
+
do $$
|
|
122
|
+
begin
|
|
123
|
+
if not exists (
|
|
124
|
+
select 1 from pg_policies where tablename = 'healthcheck' and policyname = 'Enable update for authenticated users on healthcheck'
|
|
125
|
+
) then
|
|
126
|
+
create policy "Enable update for authenticated users on healthcheck"
|
|
127
|
+
on public.healthcheck
|
|
128
|
+
for update
|
|
129
|
+
to authenticated, dashboard_user
|
|
130
|
+
using (true)
|
|
131
|
+
with check (true);
|
|
132
|
+
end if;
|
|
133
|
+
end
|
|
134
|
+
$$;
|
|
59
135
|
|
|
60
136
|
-- Profiles
|
|
61
|
-
create table profiles (
|
|
137
|
+
create table if not exists public.profiles (
|
|
62
138
|
id uuid references auth.users on delete cascade not null primary key,
|
|
63
139
|
updated_at timestamp with time zone,
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
140
|
+
username text,
|
|
141
|
+
display_name text,
|
|
142
|
+
is_admin boolean not null default false,
|
|
143
|
+
constraint username_length check (char_length(username) >= 3)
|
|
67
144
|
);
|
|
68
145
|
|
|
69
146
|
alter table public.profiles enable row level security;
|
|
70
147
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
for
|
|
148
|
+
do $$
|
|
149
|
+
begin
|
|
150
|
+
if not exists (
|
|
151
|
+
select 1 from pg_policies where tablename = 'profiles' and policyname = 'Enable read access for authenticated users'
|
|
152
|
+
) then
|
|
153
|
+
create policy "Enable read access for authenticated users"
|
|
154
|
+
on public.profiles
|
|
155
|
+
for select
|
|
156
|
+
to authenticated, dashboard_user
|
|
157
|
+
using (true);
|
|
158
|
+
end if;
|
|
159
|
+
end
|
|
160
|
+
$$;
|
|
75
161
|
|
|
76
162
|
--- inserts a row into public.profiles
|
|
77
|
-
create function public.handle_new_user()
|
|
163
|
+
create or replace function public.handle_new_user()
|
|
78
164
|
returns trigger
|
|
79
165
|
language plpgsql
|
|
80
166
|
security definer set search_path = ''
|
|
81
167
|
as $$
|
|
82
168
|
begin
|
|
83
|
-
insert into public.profiles (id,
|
|
84
|
-
values (new.id, new.raw_user_meta_data ->> '
|
|
169
|
+
insert into public.profiles (id, username, display_name)
|
|
170
|
+
values (new.id, new.raw_user_meta_data ->> 'username', new.raw_user_meta_data ->> 'display_name');
|
|
85
171
|
return new;
|
|
86
172
|
end;
|
|
87
173
|
$$;
|
|
88
174
|
--- trigger the function every time a user is created
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
175
|
+
do $$
|
|
176
|
+
begin
|
|
177
|
+
if not exists (
|
|
178
|
+
select 1 from pg_trigger where tgname = 'on_auth_user_created'
|
|
179
|
+
) then
|
|
180
|
+
create trigger on_auth_user_created
|
|
181
|
+
after insert on auth.users
|
|
182
|
+
for each row execute procedure public.handle_new_user();
|
|
183
|
+
end if;
|
|
184
|
+
end
|
|
185
|
+
$$;
|
|
@@ -7,7 +7,7 @@ interface Payload {
|
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* Splits a SQL string into individual statements, correctly handling
|
|
10
|
-
* $$ dollar-quoted blocks
|
|
10
|
+
* $$ dollar-quoted blocks, single-quoted strings, and -- comments.
|
|
11
11
|
*/
|
|
12
12
|
function splitStatements(sql: string): string[] {
|
|
13
13
|
const statements: string[] = []
|
|
@@ -32,6 +32,28 @@ function splitStatements(sql: string): string[] {
|
|
|
32
32
|
continue
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
+
// Check for single-quoted strings (handle '' escapes)
|
|
36
|
+
if (sql[i] === `'`) {
|
|
37
|
+
current += sql[i]
|
|
38
|
+
i++
|
|
39
|
+
while (i < sql.length) {
|
|
40
|
+
if (sql[i] === `'` && sql[i + 1] === `'`) {
|
|
41
|
+
// Escaped quote
|
|
42
|
+
current += `''`
|
|
43
|
+
i += 2
|
|
44
|
+
continue
|
|
45
|
+
}
|
|
46
|
+
if (sql[i] === `'`) {
|
|
47
|
+
current += sql[i]
|
|
48
|
+
i++
|
|
49
|
+
break
|
|
50
|
+
}
|
|
51
|
+
current += sql[i]
|
|
52
|
+
i++
|
|
53
|
+
}
|
|
54
|
+
continue
|
|
55
|
+
}
|
|
56
|
+
|
|
35
57
|
// Check for single-line comments
|
|
36
58
|
if (sql[i] === '-' && sql[i + 1] === '-') {
|
|
37
59
|
while (i < sql.length && sql[i] !== '\n') {
|
|
@@ -96,13 +118,6 @@ export default defineEventHandler(async (event) => {
|
|
|
96
118
|
await sql.unsafe(statement)
|
|
97
119
|
}
|
|
98
120
|
|
|
99
|
-
// Set the first_setup flag in the healthcheck table to false
|
|
100
|
-
await sql`
|
|
101
|
-
UPDATE healthcheck
|
|
102
|
-
SET check_value = 'false'
|
|
103
|
-
WHERE check_name = 'first_setup';
|
|
104
|
-
`
|
|
105
|
-
|
|
106
121
|
return {
|
|
107
122
|
success: true,
|
|
108
123
|
message: 'Database setup completed successfully.',
|
|
@@ -1,28 +1,55 @@
|
|
|
1
1
|
import { serverSupabaseClient } from '#supabase/server'
|
|
2
2
|
|
|
3
|
+
interface Payload {
|
|
4
|
+
username: string
|
|
5
|
+
display_name: string
|
|
6
|
+
email: string
|
|
7
|
+
password: string
|
|
8
|
+
is_admin?: boolean
|
|
9
|
+
}
|
|
10
|
+
|
|
3
11
|
export default defineEventHandler(async (event) => {
|
|
4
12
|
const client = await serverSupabaseClient<Database>(event)
|
|
5
13
|
|
|
6
|
-
const body = await readBody(event)
|
|
14
|
+
const body = await readBody<Payload>(event)
|
|
7
15
|
|
|
8
16
|
const { data, error } = await client.auth.signUp({
|
|
9
17
|
email: body.email,
|
|
10
18
|
password: body.password,
|
|
11
19
|
options: {
|
|
12
20
|
data: {
|
|
13
|
-
|
|
14
|
-
|
|
21
|
+
username: body.username,
|
|
22
|
+
display_name: body.display_name,
|
|
23
|
+
is_admin: body.is_admin || false,
|
|
15
24
|
},
|
|
16
25
|
},
|
|
17
26
|
})
|
|
18
27
|
|
|
19
28
|
if (error) {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
cause: error.cause,
|
|
29
|
+
return {
|
|
30
|
+
success: false,
|
|
23
31
|
message: error.message,
|
|
24
|
-
|
|
32
|
+
error,
|
|
33
|
+
}
|
|
25
34
|
}
|
|
26
35
|
|
|
27
|
-
|
|
36
|
+
// Set the first_setup flag in the healthcheck table to false
|
|
37
|
+
const { error: healthcheckError } = await client
|
|
38
|
+
.from('healthcheck')
|
|
39
|
+
.update({ config_value: 'false' })
|
|
40
|
+
.eq('config_name', 'first_setup')
|
|
41
|
+
|
|
42
|
+
if (healthcheckError) {
|
|
43
|
+
return {
|
|
44
|
+
success: false,
|
|
45
|
+
message: healthcheckError.message,
|
|
46
|
+
error: healthcheckError,
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return {
|
|
51
|
+
success: true,
|
|
52
|
+
message: 'User registered successfully',
|
|
53
|
+
data,
|
|
54
|
+
}
|
|
28
55
|
})
|