give twilio its own table
This commit is contained in:
parent
3d562e4009
commit
aeaafcefe1
5 changed files with 75 additions and 33 deletions
|
|
@ -34,6 +34,7 @@ model User {
|
|||
model Tenant {
|
||||
id String @id @default(uuid())
|
||||
clerkOrganizationId String @unique
|
||||
|
||||
users User[]
|
||||
tenantConfig TenantConfig?
|
||||
|
||||
|
|
@ -49,6 +50,17 @@ model TenantConfig {
|
|||
tenant Tenant @relation(fields: [tenantId], references: [id])
|
||||
tenantId String @unique
|
||||
|
||||
twilioConfig TwilioConfig?
|
||||
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
}
|
||||
|
||||
model TwilioConfig {
|
||||
id String @id @default(uuid())
|
||||
tenantConfig TenantConfig @relation(fields: [tenantConfigId], references: [id])
|
||||
tenantConfigId String @unique
|
||||
|
||||
accountSID String
|
||||
authToken String
|
||||
phoneNumber String
|
||||
|
|
|
|||
|
|
@ -10,7 +10,15 @@ export const load = async (event) => {
|
|||
|
||||
const configs = await prisma.tenantConfig.findUnique({
|
||||
where: { tenantId: tenantId },
|
||||
select: { accountSID: true, authToken: true, phoneNumber: true },
|
||||
select: {
|
||||
twilioConfig: {
|
||||
select: {
|
||||
accountSID: true,
|
||||
authToken: true,
|
||||
phoneNumber: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
return {
|
||||
|
|
@ -23,21 +31,21 @@ export const actions = {
|
|||
const form = await event.request.formData();
|
||||
const tenantId = event.locals.tenant.id;
|
||||
|
||||
if (!form.has('accountSID')) {
|
||||
if (!form.has('twilioAccountSID')) {
|
||||
return fail(400, { error: 'account_sid_missing' });
|
||||
}
|
||||
if (!form.has('authToken')) {
|
||||
if (!form.has('twilioAuthToken')) {
|
||||
return fail(400, { error: 'auth_token_missing' });
|
||||
}
|
||||
if (!form.has('phoneNumber')) {
|
||||
if (!form.has('twilioPhoneNumber')) {
|
||||
return fail(400, { error: 'phone_number_missing' });
|
||||
}
|
||||
|
||||
const accountSID = form.get('accountSID');
|
||||
const accountSID = form.get('twilioAccountSID');
|
||||
if (typeof accountSID !== 'string') {
|
||||
return fail(400, { error: 'invalid_account_sid' });
|
||||
}
|
||||
const authToken = form.get('authToken');
|
||||
const authToken = form.get('twilioAuthToken');
|
||||
if (typeof authToken !== 'string') {
|
||||
return fail(400, { error: 'invalid_auth_token' });
|
||||
}
|
||||
|
|
@ -45,7 +53,7 @@ export const actions = {
|
|||
success: phoneSuccess,
|
||||
data: phoneNumber,
|
||||
error: phoneError,
|
||||
} = zod.string().regex(PhoneRegex).safeParse(form.get('phoneNumber'));
|
||||
} = zod.string().regex(PhoneRegex).safeParse(form.get('twilioPhoneNumber'));
|
||||
if (!phoneSuccess) {
|
||||
logger.error(phoneError);
|
||||
return fail(400, { error: 'invalid_phone_number' });
|
||||
|
|
@ -57,17 +65,25 @@ export const actions = {
|
|||
},
|
||||
create: {
|
||||
tenantId: tenantId,
|
||||
twilioConfig: {
|
||||
create: {
|
||||
accountSID: encrypt(accountSID),
|
||||
authToken: encrypt(authToken),
|
||||
phoneNumber: encrypt(phoneNumber),
|
||||
},
|
||||
},
|
||||
},
|
||||
update: {
|
||||
tenantId: tenantId,
|
||||
twilioConfig: {
|
||||
update: {
|
||||
accountSID: accountSID,
|
||||
authToken: authToken,
|
||||
phoneNumber: phoneNumber,
|
||||
},
|
||||
select: { accountSID: true, authToken: true, phoneNumber: true },
|
||||
},
|
||||
},
|
||||
select: { twilioConfig: true },
|
||||
});
|
||||
|
||||
return {
|
||||
|
|
|
|||
|
|
@ -31,10 +31,11 @@
|
|||
<form id="sms" method="POST" action="?/update" use:enhance>
|
||||
<div class="card-body">
|
||||
<Divider />
|
||||
<!-- Twilio -->
|
||||
<h2 class="text-2xl font-semibold">{messages.settings_category_twilio()}</h2>
|
||||
<TextInput
|
||||
defaultvalue={configs?.accountSID}
|
||||
name="accountSID"
|
||||
defaultvalue={configs?.twilioConfig?.accountSID}
|
||||
name="twilioAccountSID"
|
||||
placeholder="..."
|
||||
bordered
|
||||
fade
|
||||
|
|
@ -47,8 +48,8 @@
|
|||
{/snippet}
|
||||
</TextInput>
|
||||
<TextInput
|
||||
defaultvalue={configs?.authToken}
|
||||
name="authToken"
|
||||
defaultvalue={configs?.twilioConfig?.authToken}
|
||||
name="twilioAuthToken"
|
||||
placeholder="..."
|
||||
type="password"
|
||||
bordered
|
||||
|
|
@ -62,8 +63,8 @@
|
|||
{/snippet}
|
||||
</TextInput>
|
||||
<TextInput
|
||||
defaultvalue={configs?.phoneNumber}
|
||||
name="phoneNumber"
|
||||
defaultvalue={configs?.twilioConfig?.phoneNumber}
|
||||
name="twilioPhoneNumber"
|
||||
placeholder="+1XXX-XXX-XXXX"
|
||||
bordered
|
||||
fade
|
||||
|
|
|
|||
|
|
@ -11,15 +11,29 @@ export const load = async (event) => {
|
|||
|
||||
const configs = await prisma.tenantConfig.findUnique({
|
||||
where: { tenantId: tenantId },
|
||||
select: {
|
||||
twilioConfig: {
|
||||
select: {
|
||||
accountSID: true,
|
||||
authToken: true,
|
||||
phoneNumber: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const { success, error: validationError } = zod
|
||||
.object({
|
||||
accountSID: zod.string(),
|
||||
})
|
||||
.safeParse(configs?.twilioConfig);
|
||||
|
||||
if (!success) {
|
||||
logger.warn(validationError.message);
|
||||
}
|
||||
|
||||
return {
|
||||
configs: configs,
|
||||
isTwilioConfigured: success,
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@
|
|||
form: ActionData;
|
||||
};
|
||||
let { data, form }: Props = $props();
|
||||
let isConfigMissing = $derived(!data.configs);
|
||||
</script>
|
||||
|
||||
{#snippet PhoneLabel()}
|
||||
|
|
@ -35,7 +34,7 @@
|
|||
{/snippet}
|
||||
<span>{form.error}</span>
|
||||
</Alert>
|
||||
{:else if isConfigMissing}
|
||||
{:else if !data.isTwilioConfigured}
|
||||
<Alert status="warning">
|
||||
{#snippet icon()}
|
||||
<TriangleAlert />
|
||||
|
|
@ -53,7 +52,7 @@
|
|||
<form id="sms" method="POST" action="?/push" use:enhance>
|
||||
<div class="card-body">
|
||||
<TextInput
|
||||
disabled={isConfigMissing}
|
||||
disabled={!data.isTwilioConfigured}
|
||||
type="tel"
|
||||
name="phone"
|
||||
label={PhoneLabel}
|
||||
|
|
@ -62,7 +61,7 @@
|
|||
fade
|
||||
/>
|
||||
<Textarea
|
||||
disabled={isConfigMissing}
|
||||
disabled={!data.isTwilioConfigured}
|
||||
label={MessageLabel}
|
||||
size="lg"
|
||||
error={form?.error}
|
||||
|
|
@ -72,7 +71,7 @@
|
|||
/>
|
||||
</div>
|
||||
<div class="card-actions justify-center px-8 pb-4">
|
||||
<Button disabled={isConfigMissing} type="submit" variant="outline" full>
|
||||
<Button disabled={!data.isTwilioConfigured} type="submit" variant="outline" full>
|
||||
{messages.sms_button_submit()}
|
||||
</Button>
|
||||
</div>
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue