mirror of
https://github.com/SecurityBrewery/catalyst.git
synced 2025-12-06 23:32:47 +01:00
Compare commits
3 Commits
v0.15.0-rc
...
v0.15.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4e03a52b71 | ||
|
|
e475b38ea4 | ||
|
|
e07afd0f3a |
@@ -60,7 +60,7 @@ func runHook(ctx context.Context, queries *sqlc.Queries, collection, event strin
|
|||||||
Action: event,
|
Action: event,
|
||||||
Collection: collection,
|
Collection: collection,
|
||||||
Record: record,
|
Record: record,
|
||||||
Auth: auth,
|
Auth: webhook.SanitizeUser(auth),
|
||||||
Admin: nil,
|
Admin: nil,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
"log/slog"
|
"log/slog"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/SecurityBrewery/catalyst/app/auth/usercontext"
|
"github.com/SecurityBrewery/catalyst/app/auth/usercontext"
|
||||||
"github.com/SecurityBrewery/catalyst/app/database"
|
"github.com/SecurityBrewery/catalyst/app/database"
|
||||||
@@ -35,11 +36,43 @@ func BindHooks(hooks *hook.Hooks, queries *sqlc.Queries) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Payload struct {
|
type Payload struct {
|
||||||
Action string `json:"action"`
|
Action string `json:"action"`
|
||||||
Collection string `json:"collection"`
|
Collection string `json:"collection"`
|
||||||
Record any `json:"record"`
|
Record any `json:"record"`
|
||||||
Auth *sqlc.User `json:"auth,omitempty"`
|
Auth *AuthUser `json:"auth,omitempty"`
|
||||||
Admin *sqlc.User `json:"admin,omitempty"`
|
Admin *AuthUser `json:"admin,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AuthUser struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
Username string `json:"username"`
|
||||||
|
Active bool `json:"active"`
|
||||||
|
Name *string `json:"name,omitempty"`
|
||||||
|
Email *string `json:"email,omitempty"`
|
||||||
|
Avatar *string `json:"avatar,omitempty"`
|
||||||
|
Lastresetsentat *time.Time `json:"lastresetsentat,omitempty"`
|
||||||
|
Lastverificationsentat *time.Time `json:"lastverificationsentat,omitempty"`
|
||||||
|
Created time.Time `json:"created"`
|
||||||
|
Updated time.Time `json:"updated"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func SanitizeUser(user *sqlc.User) *AuthUser {
|
||||||
|
if user == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return &AuthUser{
|
||||||
|
ID: user.ID,
|
||||||
|
Username: user.Username,
|
||||||
|
Active: user.Active,
|
||||||
|
Name: user.Name,
|
||||||
|
Email: user.Email,
|
||||||
|
Avatar: user.Avatar,
|
||||||
|
Lastresetsentat: user.Lastresetsentat,
|
||||||
|
Lastverificationsentat: user.Lastverificationsentat,
|
||||||
|
Created: user.Created,
|
||||||
|
Updated: user.Updated,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func event(ctx context.Context, queries *sqlc.Queries, event, collection string, record any) {
|
func event(ctx context.Context, queries *sqlc.Queries, event, collection string, record any) {
|
||||||
@@ -67,7 +100,7 @@ func event(ctx context.Context, queries *sqlc.Queries, event, collection string,
|
|||||||
Action: event,
|
Action: event,
|
||||||
Collection: collection,
|
Collection: collection,
|
||||||
Record: record,
|
Record: record,
|
||||||
Auth: user,
|
Auth: SanitizeUser(user),
|
||||||
Admin: nil,
|
Admin: nil,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ watch(
|
|||||||
<div v-for="(property, key) in schema?.properties" :key="key">
|
<div v-for="(property, key) in schema?.properties" :key="key">
|
||||||
<FormField v-if="property.enum" :name="key" v-slot="{ componentField }" v-model="formdata[key]">
|
<FormField v-if="property.enum" :name="key" v-slot="{ componentField }" v-model="formdata[key]">
|
||||||
<FormItem>
|
<FormItem>
|
||||||
<FormLabel :for="key" class="text-right">
|
<FormLabel :for="key" class="text-left">
|
||||||
{{ property.title }}
|
{{ property.title }}
|
||||||
</FormLabel>
|
</FormLabel>
|
||||||
<Select :id="key" class="col-span-3" v-bind="componentField">
|
<Select :id="key" class="col-span-3" v-bind="componentField">
|
||||||
@@ -87,7 +87,7 @@ watch(
|
|||||||
v-model="formdata[key]"
|
v-model="formdata[key]"
|
||||||
>
|
>
|
||||||
<FormItem>
|
<FormItem>
|
||||||
<FormLabel :for="key" class="text-right">
|
<FormLabel :for="key" class="text-left">
|
||||||
{{ property.title }}
|
{{ property.title }}
|
||||||
</FormLabel>
|
</FormLabel>
|
||||||
<Input :id="key" class="col-span-3" v-bind="componentField" />
|
<Input :id="key" class="col-span-3" v-bind="componentField" />
|
||||||
@@ -120,7 +120,7 @@ watch(
|
|||||||
v-model="formdata[key]"
|
v-model="formdata[key]"
|
||||||
>
|
>
|
||||||
<FormItem>
|
<FormItem>
|
||||||
<FormLabel :for="key" class="text-right">
|
<FormLabel :for="key" class="text-left">
|
||||||
{{ property.title }}
|
{{ property.title }}
|
||||||
</FormLabel>
|
</FormLabel>
|
||||||
<Input :id="key" class="col-span-3" type="number" v-bind="componentField" />
|
<Input :id="key" class="col-span-3" type="number" v-bind="componentField" />
|
||||||
|
|||||||
@@ -133,7 +133,7 @@ const permissionItems = computed(() => config.value?.permissions || [])
|
|||||||
<form @submit="onSubmit" class="flex w-full flex-col items-start gap-4">
|
<form @submit="onSubmit" class="flex w-full flex-col items-start gap-4">
|
||||||
<FormField name="name" v-slot="{ componentField }" validate-on-input>
|
<FormField name="name" v-slot="{ componentField }" validate-on-input>
|
||||||
<FormItem class="w-full">
|
<FormItem class="w-full">
|
||||||
<FormLabel for="name" class="text-right">Name</FormLabel>
|
<FormLabel for="name" class="text-left">Name</FormLabel>
|
||||||
<Input
|
<Input
|
||||||
id="name"
|
id="name"
|
||||||
class="col-span-3"
|
class="col-span-3"
|
||||||
@@ -152,7 +152,7 @@ const permissionItems = computed(() => config.value?.permissions || [])
|
|||||||
>
|
>
|
||||||
<FormItem id="permissions" class="w-full">
|
<FormItem id="permissions" class="w-full">
|
||||||
<div class="space-y-0.5">
|
<div class="space-y-0.5">
|
||||||
<FormLabel for="permissions" class="text-right">Permissions</FormLabel>
|
<FormLabel for="permissions" class="text-left">Permissions</FormLabel>
|
||||||
</div>
|
</div>
|
||||||
<FormControl>
|
<FormControl>
|
||||||
<MultiSelect
|
<MultiSelect
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ watch(
|
|||||||
<form @submit="onSubmit" @change="change">
|
<form @submit="onSubmit" @change="change">
|
||||||
<FormField name="group" v-slot="{ componentField }">
|
<FormField name="group" v-slot="{ componentField }">
|
||||||
<FormItem>
|
<FormItem>
|
||||||
<FormLabel for="group" class="text-right"> Group</FormLabel>
|
<FormLabel for="group" class="text-left"> Group</FormLabel>
|
||||||
<Select id="group" v-bind="componentField">
|
<Select id="group" v-bind="componentField">
|
||||||
<SelectTrigger>
|
<SelectTrigger>
|
||||||
<SelectValue placeholder="Select a group" />
|
<SelectValue placeholder="Select a group" />
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import {
|
|||||||
<template>
|
<template>
|
||||||
<FormField name="actiondata.requirements" v-slot="{ componentField }">
|
<FormField name="actiondata.requirements" v-slot="{ componentField }">
|
||||||
<FormItem>
|
<FormItem>
|
||||||
<FormLabel for="requirements" class="text-right">requirements.txt</FormLabel>
|
<FormLabel for="requirements" class="text-left">requirements.txt</FormLabel>
|
||||||
<FormControl>
|
<FormControl>
|
||||||
<GrowTextarea id="requirements" class="col-span-3" v-bind="componentField" />
|
<GrowTextarea id="requirements" class="col-span-3" v-bind="componentField" />
|
||||||
</FormControl>
|
</FormControl>
|
||||||
@@ -23,7 +23,7 @@ import {
|
|||||||
</FormField>
|
</FormField>
|
||||||
<FormField name="actiondata.script" v-slot="{ componentField }" validate-on-input>
|
<FormField name="actiondata.script" v-slot="{ componentField }" validate-on-input>
|
||||||
<FormItem>
|
<FormItem>
|
||||||
<FormLabel for="script" class="text-right">Script</FormLabel>
|
<FormLabel for="script" class="text-left">Script</FormLabel>
|
||||||
<FormControl>
|
<FormControl>
|
||||||
<GrowTextarea id="script" class="col-span-3" v-bind="componentField" />
|
<GrowTextarea id="script" class="col-span-3" v-bind="componentField" />
|
||||||
</FormControl>
|
</FormControl>
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import { Input } from '@/components/ui/input'
|
|||||||
<template>
|
<template>
|
||||||
<FormField name="actiondata.headers" v-slot="{ value, handleChange }">
|
<FormField name="actiondata.headers" v-slot="{ value, handleChange }">
|
||||||
<FormItem>
|
<FormItem>
|
||||||
<FormLabel for="headers" class="text-right">Headers</FormLabel>
|
<FormLabel for="headers" class="text-left">Headers</FormLabel>
|
||||||
<FormControl>
|
<FormControl>
|
||||||
<GrowListTextarea
|
<GrowListTextarea
|
||||||
id="headers"
|
id="headers"
|
||||||
@@ -29,7 +29,7 @@ import { Input } from '@/components/ui/input'
|
|||||||
</FormField>
|
</FormField>
|
||||||
<FormField name="actiondata.url" v-slot="{ componentField }" validate-on-input>
|
<FormField name="actiondata.url" v-slot="{ componentField }" validate-on-input>
|
||||||
<FormItem>
|
<FormItem>
|
||||||
<FormLabel for="url" class="text-right">URL</FormLabel>
|
<FormLabel for="url" class="text-left">URL</FormLabel>
|
||||||
<FormControl>
|
<FormControl>
|
||||||
<Input id="url" v-bind="componentField" placeholder="https://example.com/webhook" />
|
<Input id="url" v-bind="componentField" placeholder="https://example.com/webhook" />
|
||||||
</FormControl>
|
</FormControl>
|
||||||
|
|||||||
@@ -267,7 +267,7 @@ const curlExample = computed(() => {
|
|||||||
<form @submit="onSubmit" class="flex w-full flex-col items-start gap-4">
|
<form @submit="onSubmit" class="flex w-full flex-col items-start gap-4">
|
||||||
<FormField name="name" v-slot="{ componentField }" validate-on-input>
|
<FormField name="name" v-slot="{ componentField }" validate-on-input>
|
||||||
<FormItem class="w-full">
|
<FormItem class="w-full">
|
||||||
<FormLabel for="name" class="text-right">Name</FormLabel>
|
<FormLabel for="name" class="text-left">Name</FormLabel>
|
||||||
<Input id="name" class="col-span-3" v-bind="componentField" />
|
<Input id="name" class="col-span-3" v-bind="componentField" />
|
||||||
<FormMessage />
|
<FormMessage />
|
||||||
</FormItem>
|
</FormItem>
|
||||||
@@ -280,7 +280,7 @@ const curlExample = computed(() => {
|
|||||||
<CardContent class="flex flex-col gap-4">
|
<CardContent class="flex flex-col gap-4">
|
||||||
<FormField name="trigger" v-slot="{ componentField }" validate-on-input>
|
<FormField name="trigger" v-slot="{ componentField }" validate-on-input>
|
||||||
<FormItem>
|
<FormItem>
|
||||||
<FormLabel for="trigger" class="text-right">Type</FormLabel>
|
<FormLabel for="trigger" class="text-left">Type</FormLabel>
|
||||||
<FormControl>
|
<FormControl>
|
||||||
<Select id="trigger" class="col-span-3" v-bind="componentField">
|
<Select id="trigger" class="col-span-3" v-bind="componentField">
|
||||||
<SelectTrigger class="font-medium">
|
<SelectTrigger class="font-medium">
|
||||||
@@ -321,7 +321,7 @@ const curlExample = computed(() => {
|
|||||||
<CardContent class="flex flex-col gap-4">
|
<CardContent class="flex flex-col gap-4">
|
||||||
<FormField name="action" v-slot="{ componentField }" validate-on-input>
|
<FormField name="action" v-slot="{ componentField }" validate-on-input>
|
||||||
<FormItem>
|
<FormItem>
|
||||||
<FormLabel for="action" class="text-right">Type</FormLabel>
|
<FormLabel for="action" class="text-left">Type</FormLabel>
|
||||||
<FormControl>
|
<FormControl>
|
||||||
<Select id="action" class="col-span-3" v-bind="componentField">
|
<Select id="action" class="col-span-3" v-bind="componentField">
|
||||||
<SelectTrigger class="font-medium">
|
<SelectTrigger class="font-medium">
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import {
|
|||||||
<template>
|
<template>
|
||||||
<FormField name="triggerdata.collections" v-slot="{ componentField }" validate-on-input>
|
<FormField name="triggerdata.collections" v-slot="{ componentField }" validate-on-input>
|
||||||
<FormItem>
|
<FormItem>
|
||||||
<FormLabel for="collections" class="text-right">Collections</FormLabel>
|
<FormLabel for="collections" class="text-left">Collections</FormLabel>
|
||||||
<FormControl>
|
<FormControl>
|
||||||
<TriggerHookFormFieldCollections id="collections" v-bind="componentField" />
|
<TriggerHookFormFieldCollections id="collections" v-bind="componentField" />
|
||||||
</FormControl>
|
</FormControl>
|
||||||
@@ -25,7 +25,7 @@ import {
|
|||||||
|
|
||||||
<FormField name="triggerdata.events" v-slot="{ componentField }" validate-on-input>
|
<FormField name="triggerdata.events" v-slot="{ componentField }" validate-on-input>
|
||||||
<FormItem>
|
<FormItem>
|
||||||
<FormLabel for="events" class="text-right">Events</FormLabel>
|
<FormLabel for="events" class="text-left">Events</FormLabel>
|
||||||
<FormControl>
|
<FormControl>
|
||||||
<TriggerHookFormFieldEvents id="events" v-bind="componentField" />
|
<TriggerHookFormFieldEvents id="events" v-bind="componentField" />
|
||||||
</FormControl>
|
</FormControl>
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import { Input } from '@/components/ui/input'
|
|||||||
<template>
|
<template>
|
||||||
<FormField name="triggerdata.expression" v-slot="{ componentField }" validate-on-input>
|
<FormField name="triggerdata.expression" v-slot="{ componentField }" validate-on-input>
|
||||||
<FormItem>
|
<FormItem>
|
||||||
<FormLabel for="expression" class="text-right"> Cron Expression </FormLabel>
|
<FormLabel for="expression" class="text-left"> Cron Expression </FormLabel>
|
||||||
<FormControl>
|
<FormControl>
|
||||||
<Input
|
<Input
|
||||||
id="expression"
|
id="expression"
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import { Input } from '@/components/ui/input'
|
|||||||
<template>
|
<template>
|
||||||
<FormField name="triggerdata.token" v-slot="{ componentField }" validate-on-input>
|
<FormField name="triggerdata.token" v-slot="{ componentField }" validate-on-input>
|
||||||
<FormItem>
|
<FormItem>
|
||||||
<FormLabel for="token" class="text-right">Token</FormLabel>
|
<FormLabel for="token" class="text-left">Token</FormLabel>
|
||||||
<FormControl>
|
<FormControl>
|
||||||
<Input id="token" class="col-span-3" v-bind="componentField" placeholder="Enter a token" />
|
<Input id="token" class="col-span-3" v-bind="componentField" placeholder="Enter a token" />
|
||||||
</FormControl>
|
</FormControl>
|
||||||
@@ -27,7 +27,7 @@ import { Input } from '@/components/ui/input'
|
|||||||
|
|
||||||
<FormField name="triggerdata.path" v-slot="{ componentField }" validate-on-input>
|
<FormField name="triggerdata.path" v-slot="{ componentField }" validate-on-input>
|
||||||
<FormItem>
|
<FormItem>
|
||||||
<FormLabel for="path" class="text-right">Path</FormLabel>
|
<FormLabel for="path" class="text-left">Path</FormLabel>
|
||||||
<FormControl>
|
<FormControl>
|
||||||
<Input id="path" class="col-span-3" v-bind="componentField" placeholder="Enter a path" />
|
<Input id="path" class="col-span-3" v-bind="componentField" placeholder="Enter a path" />
|
||||||
</FormControl>
|
</FormControl>
|
||||||
|
|||||||
@@ -225,7 +225,7 @@ const onSubmit = handleSubmit((vals) => {
|
|||||||
<form @submit="onSubmit" class="flex w-full flex-col items-start gap-4">
|
<form @submit="onSubmit" class="flex w-full flex-col items-start gap-4">
|
||||||
<FormField name="meta.appName" v-slot="{ componentField }" validate-on-input>
|
<FormField name="meta.appName" v-slot="{ componentField }" validate-on-input>
|
||||||
<FormItem class="w-full">
|
<FormItem class="w-full">
|
||||||
<FormLabel for="meta.appName" class="text-right">App Name</FormLabel>
|
<FormLabel for="meta.appName" class="text-left">App Name</FormLabel>
|
||||||
<Input id="meta.appName" class="col-span-3" v-bind="componentField" />
|
<Input id="meta.appName" class="col-span-3" v-bind="componentField" />
|
||||||
<FormMessage />
|
<FormMessage />
|
||||||
</FormItem>
|
</FormItem>
|
||||||
@@ -233,7 +233,7 @@ const onSubmit = handleSubmit((vals) => {
|
|||||||
|
|
||||||
<FormField name="meta.appUrl" v-slot="{ componentField }" validate-on-input>
|
<FormField name="meta.appUrl" v-slot="{ componentField }" validate-on-input>
|
||||||
<FormItem class="w-full">
|
<FormItem class="w-full">
|
||||||
<FormLabel for="meta.appUrl" class="text-right">App URL</FormLabel>
|
<FormLabel for="meta.appUrl" class="text-left">App URL</FormLabel>
|
||||||
<Input id="meta.appUrl" class="col-span-3" v-bind="componentField" />
|
<Input id="meta.appUrl" class="col-span-3" v-bind="componentField" />
|
||||||
<FormMessage />
|
<FormMessage />
|
||||||
</FormItem>
|
</FormItem>
|
||||||
@@ -241,7 +241,7 @@ const onSubmit = handleSubmit((vals) => {
|
|||||||
|
|
||||||
<FormField name="meta.senderName" v-slot="{ componentField }" validate-on-input>
|
<FormField name="meta.senderName" v-slot="{ componentField }" validate-on-input>
|
||||||
<FormItem class="w-full">
|
<FormItem class="w-full">
|
||||||
<FormLabel for="meta.senderName" class="text-right">Sender Name</FormLabel>
|
<FormLabel for="meta.senderName" class="text-left">Sender Name</FormLabel>
|
||||||
<Input id="meta.senderName" class="col-span-3" v-bind="componentField" />
|
<Input id="meta.senderName" class="col-span-3" v-bind="componentField" />
|
||||||
<FormMessage />
|
<FormMessage />
|
||||||
</FormItem>
|
</FormItem>
|
||||||
@@ -249,7 +249,7 @@ const onSubmit = handleSubmit((vals) => {
|
|||||||
|
|
||||||
<FormField name="meta.senderAddress" v-slot="{ componentField }" validate-on-input>
|
<FormField name="meta.senderAddress" v-slot="{ componentField }" validate-on-input>
|
||||||
<FormItem class="w-full">
|
<FormItem class="w-full">
|
||||||
<FormLabel for="meta.senderAddress" class="text-right">Sender Address</FormLabel>
|
<FormLabel for="meta.senderAddress" class="text-left">Sender Address</FormLabel>
|
||||||
<Input id="meta.senderAddress" type="email" class="col-span-3" v-bind="componentField" />
|
<Input id="meta.senderAddress" type="email" class="col-span-3" v-bind="componentField" />
|
||||||
<FormMessage />
|
<FormMessage />
|
||||||
</FormItem>
|
</FormItem>
|
||||||
@@ -262,7 +262,7 @@ const onSubmit = handleSubmit((vals) => {
|
|||||||
<CardContent class="flex flex-col gap-4">
|
<CardContent class="flex flex-col gap-4">
|
||||||
<FormField name="maxDays" v-slot="{ componentField }" validate-on-input>
|
<FormField name="maxDays" v-slot="{ componentField }" validate-on-input>
|
||||||
<FormItem class="w-full">
|
<FormItem class="w-full">
|
||||||
<FormLabel for="maxDays" class="text-right">Max Days</FormLabel>
|
<FormLabel for="maxDays" class="text-left">Max Days</FormLabel>
|
||||||
<Input id="maxDays" type="number" class="col-span-3" v-bind="componentField" />
|
<Input id="maxDays" type="number" class="col-span-3" v-bind="componentField" />
|
||||||
<FormMessage />
|
<FormMessage />
|
||||||
</FormItem>
|
</FormItem>
|
||||||
@@ -270,7 +270,7 @@ const onSubmit = handleSubmit((vals) => {
|
|||||||
|
|
||||||
<FormField name="logLevel" v-slot="{ componentField }" validate-on-input>
|
<FormField name="logLevel" v-slot="{ componentField }" validate-on-input>
|
||||||
<FormItem>
|
<FormItem>
|
||||||
<FormLabel for="logLevel" class="text-right">Log Level</FormLabel>
|
<FormLabel for="logLevel" class="text-left">Log Level</FormLabel>
|
||||||
<FormControl>
|
<FormControl>
|
||||||
<Select id="logLevel" class="col-span-3" v-bind="componentField">
|
<Select id="logLevel" class="col-span-3" v-bind="componentField">
|
||||||
<SelectTrigger class="font-medium">
|
<SelectTrigger class="font-medium">
|
||||||
@@ -328,7 +328,7 @@ const onSubmit = handleSubmit((vals) => {
|
|||||||
|
|
||||||
<FormField name="smtp.host" v-slot="{ componentField }" validate-on-input>
|
<FormField name="smtp.host" v-slot="{ componentField }" validate-on-input>
|
||||||
<FormItem class="w-full">
|
<FormItem class="w-full">
|
||||||
<FormLabel for="smtp.host" class="text-right">Host</FormLabel>
|
<FormLabel for="smtp.host" class="text-left">Host</FormLabel>
|
||||||
<Input id="smtp.host" class="col-span-3" v-bind="componentField" />
|
<Input id="smtp.host" class="col-span-3" v-bind="componentField" />
|
||||||
<FormMessage />
|
<FormMessage />
|
||||||
<FormDescription>SMTP server hostname (e.g., smtp.gmail.com)</FormDescription>
|
<FormDescription>SMTP server hostname (e.g., smtp.gmail.com)</FormDescription>
|
||||||
@@ -337,7 +337,7 @@ const onSubmit = handleSubmit((vals) => {
|
|||||||
|
|
||||||
<FormField name="smtp.port" v-slot="{ componentField }" validate-on-input>
|
<FormField name="smtp.port" v-slot="{ componentField }" validate-on-input>
|
||||||
<FormItem class="w-full">
|
<FormItem class="w-full">
|
||||||
<FormLabel for="smtp.port" class="text-right">Port</FormLabel>
|
<FormLabel for="smtp.port" class="text-left">Port</FormLabel>
|
||||||
<Input id="smtp.port" type="number" class="col-span-3" v-bind="componentField" />
|
<Input id="smtp.port" type="number" class="col-span-3" v-bind="componentField" />
|
||||||
<FormMessage />
|
<FormMessage />
|
||||||
<FormDescription>Common ports: 25, 465 (SSL), 587 (TLS)</FormDescription>
|
<FormDescription>Common ports: 25, 465 (SSL), 587 (TLS)</FormDescription>
|
||||||
@@ -346,7 +346,7 @@ const onSubmit = handleSubmit((vals) => {
|
|||||||
|
|
||||||
<FormField name="smtp.username" v-slot="{ componentField }" validate-on-input>
|
<FormField name="smtp.username" v-slot="{ componentField }" validate-on-input>
|
||||||
<FormItem class="w-full">
|
<FormItem class="w-full">
|
||||||
<FormLabel for="smtp.username" class="text-right">Username</FormLabel>
|
<FormLabel for="smtp.username" class="text-left">Username</FormLabel>
|
||||||
<Input id="smtp.username" class="col-span-3" v-bind="componentField" />
|
<Input id="smtp.username" class="col-span-3" v-bind="componentField" />
|
||||||
<FormMessage />
|
<FormMessage />
|
||||||
</FormItem>
|
</FormItem>
|
||||||
@@ -354,7 +354,7 @@ const onSubmit = handleSubmit((vals) => {
|
|||||||
|
|
||||||
<FormField name="smtp.password" v-slot="{ componentField }" validate-on-input>
|
<FormField name="smtp.password" v-slot="{ componentField }" validate-on-input>
|
||||||
<FormItem class="w-full">
|
<FormItem class="w-full">
|
||||||
<FormLabel for="smtp.password" class="text-right">Password</FormLabel>
|
<FormLabel for="smtp.password" class="text-left">Password</FormLabel>
|
||||||
<Input id="smtp.password" type="password" class="col-span-3" v-bind="componentField" />
|
<Input id="smtp.password" type="password" class="col-span-3" v-bind="componentField" />
|
||||||
<FormMessage />
|
<FormMessage />
|
||||||
</FormItem>
|
</FormItem>
|
||||||
@@ -362,7 +362,7 @@ const onSubmit = handleSubmit((vals) => {
|
|||||||
|
|
||||||
<FormField name="smtp.authMethod" v-slot="{ componentField }" validate-on-input>
|
<FormField name="smtp.authMethod" v-slot="{ componentField }" validate-on-input>
|
||||||
<FormItem>
|
<FormItem>
|
||||||
<FormLabel for="smtp.authMethod" class="text-right"> Authentication Method </FormLabel>
|
<FormLabel for="smtp.authMethod" class="text-left"> Authentication Method </FormLabel>
|
||||||
<Select id="smtp.authMethod" class="col-span-3" v-bind="componentField">
|
<Select id="smtp.authMethod" class="col-span-3" v-bind="componentField">
|
||||||
<SelectTrigger class="font-medium">
|
<SelectTrigger class="font-medium">
|
||||||
<SelectValue placeholder="Select authentication method" />
|
<SelectValue placeholder="Select authentication method" />
|
||||||
@@ -392,7 +392,7 @@ const onSubmit = handleSubmit((vals) => {
|
|||||||
|
|
||||||
<FormField name="smtp.localName" v-slot="{ componentField }" validate-on-input>
|
<FormField name="smtp.localName" v-slot="{ componentField }" validate-on-input>
|
||||||
<FormItem class="w-full">
|
<FormItem class="w-full">
|
||||||
<FormLabel for="smtp.localName" class="text-right">HELO domain</FormLabel>
|
<FormLabel for="smtp.localName" class="text-left">HELO domain</FormLabel>
|
||||||
<Input id="smtp.localName" class="col-span-3" v-bind="componentField" />
|
<Input id="smtp.localName" class="col-span-3" v-bind="componentField" />
|
||||||
<FormDescription>Optional. Leave empty to use default hostname.</FormDescription>
|
<FormDescription>Optional. Leave empty to use default hostname.</FormDescription>
|
||||||
<FormMessage />
|
<FormMessage />
|
||||||
@@ -408,7 +408,7 @@ const onSubmit = handleSubmit((vals) => {
|
|||||||
<CardContent class="flex flex-col gap-4">
|
<CardContent class="flex flex-col gap-4">
|
||||||
<FormField name="cron" v-slot="{ componentField }" validate-on-input>
|
<FormField name="cron" v-slot="{ componentField }" validate-on-input>
|
||||||
<FormItem class="w-full">
|
<FormItem class="w-full">
|
||||||
<FormLabel for="cron" class="text-right">Cron Expression</FormLabel>
|
<FormLabel for="cron" class="text-left">Cron Expression</FormLabel>
|
||||||
<Input id="cron" class="col-span-3" v-bind="componentField" />
|
<Input id="cron" class="col-span-3" v-bind="componentField" />
|
||||||
<FormMessage />
|
<FormMessage />
|
||||||
</FormItem>
|
</FormItem>
|
||||||
@@ -416,7 +416,7 @@ const onSubmit = handleSubmit((vals) => {
|
|||||||
|
|
||||||
<FormField name="cronMaxKeep" v-slot="{ componentField }" validate-on-input>
|
<FormField name="cronMaxKeep" v-slot="{ componentField }" validate-on-input>
|
||||||
<FormItem class="w-full">
|
<FormItem class="w-full">
|
||||||
<FormLabel for="cronMaxKeep" class="text-right">Max Keep</FormLabel>
|
<FormLabel for="cronMaxKeep" class="text-left">Max Keep</FormLabel>
|
||||||
<Input id="cronMaxKeep" type="number" class="col-span-3" v-bind="componentField" />
|
<Input id="cronMaxKeep" type="number" class="col-span-3" v-bind="componentField" />
|
||||||
<FormMessage />
|
<FormMessage />
|
||||||
</FormItem>
|
</FormItem>
|
||||||
|
|||||||
@@ -142,7 +142,7 @@ watch(
|
|||||||
<form @submit="onSubmit">
|
<form @submit="onSubmit">
|
||||||
<FormField name="name" v-slot="{ componentField }" v-model="name">
|
<FormField name="name" v-slot="{ componentField }" v-model="name">
|
||||||
<FormItem>
|
<FormItem>
|
||||||
<FormLabel for="name" class="text-right">Name</FormLabel>
|
<FormLabel for="name" class="text-left">Name</FormLabel>
|
||||||
<Input id="name" class="col-span-3" v-bind="componentField" />
|
<Input id="name" class="col-span-3" v-bind="componentField" />
|
||||||
<FormMessage />
|
<FormMessage />
|
||||||
</FormItem>
|
</FormItem>
|
||||||
@@ -150,7 +150,7 @@ watch(
|
|||||||
|
|
||||||
<FormField name="description" v-slot="{ componentField }" v-model="description">
|
<FormField name="description" v-slot="{ componentField }" v-model="description">
|
||||||
<FormItem>
|
<FormItem>
|
||||||
<FormLabel for="description" class="text-right">Description</FormLabel>
|
<FormLabel for="description" class="text-left">Description</FormLabel>
|
||||||
<Input id="description" class="col-span-3" v-bind="componentField" />
|
<Input id="description" class="col-span-3" v-bind="componentField" />
|
||||||
<FormMessage />
|
<FormMessage />
|
||||||
</FormItem>
|
</FormItem>
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ const change = () => validate({ mode: 'silent' }).then((res) => (submitDisabled.
|
|||||||
<form @submit="onSubmit" @change="change">
|
<form @submit="onSubmit" @change="change">
|
||||||
<FormField name="name" v-slot="{ componentField }">
|
<FormField name="name" v-slot="{ componentField }">
|
||||||
<FormItem>
|
<FormItem>
|
||||||
<FormLabel for="name" class="text-right"> Name</FormLabel>
|
<FormLabel for="name" class="text-left"> Name</FormLabel>
|
||||||
<Input id="name" v-bind="componentField" />
|
<Input id="name" v-bind="componentField" />
|
||||||
<FormMessage />
|
<FormMessage />
|
||||||
</FormItem>
|
</FormItem>
|
||||||
@@ -94,7 +94,7 @@ const change = () => validate({ mode: 'silent' }).then((res) => (submitDisabled.
|
|||||||
|
|
||||||
<FormField name="url" v-slot="{ componentField }" class="mt-2">
|
<FormField name="url" v-slot="{ componentField }" class="mt-2">
|
||||||
<FormItem>
|
<FormItem>
|
||||||
<FormLabel for="url" class="text-right"> URL</FormLabel>
|
<FormLabel for="url" class="text-left"> URL</FormLabel>
|
||||||
<Input id="url" v-bind="componentField" />
|
<Input id="url" v-bind="componentField" />
|
||||||
<FormMessage />
|
<FormMessage />
|
||||||
</FormItem>
|
</FormItem>
|
||||||
|
|||||||
@@ -138,7 +138,7 @@ const onSubmit = handleSubmit((values) => {
|
|||||||
<form @submit="onSubmit" class="flex w-full flex-col items-start gap-4">
|
<form @submit="onSubmit" class="flex w-full flex-col items-start gap-4">
|
||||||
<FormField name="singular" v-slot="{ componentField }" validate-on-input>
|
<FormField name="singular" v-slot="{ componentField }" validate-on-input>
|
||||||
<FormItem class="w-full">
|
<FormItem class="w-full">
|
||||||
<FormLabel for="singular" class="text-right">Singular</FormLabel>
|
<FormLabel for="singular" class="text-left">Singular</FormLabel>
|
||||||
<Input id="singular" class="col-span-3" v-bind="componentField" />
|
<Input id="singular" class="col-span-3" v-bind="componentField" />
|
||||||
<FormMessage />
|
<FormMessage />
|
||||||
</FormItem>
|
</FormItem>
|
||||||
@@ -146,7 +146,7 @@ const onSubmit = handleSubmit((values) => {
|
|||||||
|
|
||||||
<FormField name="plural" v-slot="{ componentField }" validate-on-input>
|
<FormField name="plural" v-slot="{ componentField }" validate-on-input>
|
||||||
<FormItem class="w-full">
|
<FormItem class="w-full">
|
||||||
<FormLabel for="plural" class="text-right">Plural</FormLabel>
|
<FormLabel for="plural" class="text-left">Plural</FormLabel>
|
||||||
<Input id="plural" class="col-span-3" v-bind="componentField" />
|
<Input id="plural" class="col-span-3" v-bind="componentField" />
|
||||||
<FormMessage />
|
<FormMessage />
|
||||||
</FormItem>
|
</FormItem>
|
||||||
|
|||||||
@@ -153,7 +153,7 @@ const onSubmit = handleSubmit((values) => emit('submit', values))
|
|||||||
<form @submit="onSubmit" class="flex w-full flex-col items-start gap-4">
|
<form @submit="onSubmit" class="flex w-full flex-col items-start gap-4">
|
||||||
<FormField name="name" v-slot="{ componentField }" validate-on-input>
|
<FormField name="name" v-slot="{ componentField }" validate-on-input>
|
||||||
<FormItem class="w-full">
|
<FormItem class="w-full">
|
||||||
<FormLabel for="name" class="text-right">Name</FormLabel>
|
<FormLabel for="name" class="text-left">Name</FormLabel>
|
||||||
<Input id="name" class="col-span-3" v-bind="componentField" />
|
<Input id="name" class="col-span-3" v-bind="componentField" />
|
||||||
<FormMessage />
|
<FormMessage />
|
||||||
</FormItem>
|
</FormItem>
|
||||||
@@ -161,7 +161,7 @@ const onSubmit = handleSubmit((values) => emit('submit', values))
|
|||||||
|
|
||||||
<FormField name="username" v-slot="{ componentField }" validate-on-input>
|
<FormField name="username" v-slot="{ componentField }" validate-on-input>
|
||||||
<FormItem class="w-full">
|
<FormItem class="w-full">
|
||||||
<FormLabel for="username" class="text-right">Username</FormLabel>
|
<FormLabel for="username" class="text-left">Username</FormLabel>
|
||||||
<Input id="username" class="col-span-3" v-bind="componentField" />
|
<Input id="username" class="col-span-3" v-bind="componentField" />
|
||||||
<FormMessage />
|
<FormMessage />
|
||||||
</FormItem>
|
</FormItem>
|
||||||
@@ -169,7 +169,7 @@ const onSubmit = handleSubmit((values) => emit('submit', values))
|
|||||||
|
|
||||||
<FormField name="email" v-slot="{ componentField }" validate-on-input>
|
<FormField name="email" v-slot="{ componentField }" validate-on-input>
|
||||||
<FormItem class="w-full">
|
<FormItem class="w-full">
|
||||||
<FormLabel for="email" class="text-right">Email</FormLabel>
|
<FormLabel for="email" class="text-left">Email</FormLabel>
|
||||||
<Input id="email" type="email" class="col-span-3" v-bind="componentField" />
|
<Input id="email" type="email" class="col-span-3" v-bind="componentField" />
|
||||||
<FormMessage />
|
<FormMessage />
|
||||||
</FormItem>
|
</FormItem>
|
||||||
|
|||||||
@@ -111,7 +111,7 @@ const onSubmit = handleSubmit((values) => emit('submit', values))
|
|||||||
<form @submit="onSubmit" class="flex w-full flex-col items-start gap-4">
|
<form @submit="onSubmit" class="flex w-full flex-col items-start gap-4">
|
||||||
<FormField name="password" v-slot="{ componentField }" validate-on-input>
|
<FormField name="password" v-slot="{ componentField }" validate-on-input>
|
||||||
<FormItem class="w-full">
|
<FormItem class="w-full">
|
||||||
<FormLabel for="password" class="text-right">Password</FormLabel>
|
<FormLabel for="password" class="text-left">Password</FormLabel>
|
||||||
<Input id="password" type="password" class="col-span-3" v-bind="componentField" />
|
<Input id="password" type="password" class="col-span-3" v-bind="componentField" />
|
||||||
<FormMessage />
|
<FormMessage />
|
||||||
</FormItem>
|
</FormItem>
|
||||||
@@ -119,7 +119,7 @@ const onSubmit = handleSubmit((values) => emit('submit', values))
|
|||||||
|
|
||||||
<FormField name="passwordConfirm" v-slot="{ componentField }" validate-on-input>
|
<FormField name="passwordConfirm" v-slot="{ componentField }" validate-on-input>
|
||||||
<FormItem class="w-full">
|
<FormItem class="w-full">
|
||||||
<FormLabel for="passwordConfirm" class="text-right">Confirm Password</FormLabel>
|
<FormLabel for="passwordConfirm" class="text-left">Confirm Password</FormLabel>
|
||||||
<Input id="passwordConfirm" type="password" class="col-span-3" v-bind="componentField" />
|
<Input id="passwordConfirm" type="password" class="col-span-3" v-bind="componentField" />
|
||||||
<FormMessage />
|
<FormMessage />
|
||||||
</FormItem>
|
</FormItem>
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ watch(
|
|||||||
<form @submit="onSubmit" @change="change">
|
<form @submit="onSubmit" @change="change">
|
||||||
<FormField name="user" v-slot="{ componentField }">
|
<FormField name="user" v-slot="{ componentField }">
|
||||||
<FormItem>
|
<FormItem>
|
||||||
<FormLabel for="user" class="text-right"> User</FormLabel>
|
<FormLabel for="user" class="text-left"> User</FormLabel>
|
||||||
<Select id="user" v-bind="componentField">
|
<Select id="user" v-bind="componentField">
|
||||||
<SelectTrigger>
|
<SelectTrigger>
|
||||||
<SelectValue placeholder="Select a user" />
|
<SelectValue placeholder="Select a user" />
|
||||||
|
|||||||
@@ -58,14 +58,6 @@ const count = (id: string) => {
|
|||||||
Open Catalyst Handbook
|
Open Catalyst Handbook
|
||||||
<ExternalLink class="ml-2 h-4 w-4" />
|
<ExternalLink class="ml-2 h-4 w-4" />
|
||||||
</a>
|
</a>
|
||||||
<a
|
|
||||||
href="/_/"
|
|
||||||
target="_blank"
|
|
||||||
class="flex items-center rounded border p-2 text-blue-500 hover:bg-accent"
|
|
||||||
>
|
|
||||||
Open Admin Interface
|
|
||||||
<ExternalLink class="ml-2 h-4 w-4" />
|
|
||||||
</a>
|
|
||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
<Card>
|
<Card>
|
||||||
@@ -118,14 +110,6 @@ const count = (id: string) => {
|
|||||||
Open Catalyst Handbook
|
Open Catalyst Handbook
|
||||||
<ExternalLink class="ml-2 h-4 w-4" />
|
<ExternalLink class="ml-2 h-4 w-4" />
|
||||||
</a>
|
</a>
|
||||||
<a
|
|
||||||
href="/_/"
|
|
||||||
target="_blank"
|
|
||||||
class="flex items-center rounded border p-2 text-blue-500 hover:bg-accent"
|
|
||||||
>
|
|
||||||
Open Admin Interface
|
|
||||||
<ExternalLink class="ml-2 h-4 w-4" />
|
|
||||||
</a>
|
|
||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
<Card>
|
<Card>
|
||||||
|
|||||||
Reference in New Issue
Block a user