diff --git a/src/ambient.d.ts b/src/ambient.d.ts
index 442cf55..05afb5e 100644
--- a/src/ambient.d.ts
+++ b/src/ambient.d.ts
@@ -63,6 +63,7 @@ type Config = {
security: {
passwordStrength: number;
};
+ defaultGroup?: string | null;
};
type Option = {
diff --git a/src/lib/components/admin/SettingsForm/DefaultGroup.svelte b/src/lib/components/admin/SettingsForm/DefaultGroup.svelte
new file mode 100644
index 0000000..fe8f729
--- /dev/null
+++ b/src/lib/components/admin/SettingsForm/DefaultGroup.svelte
@@ -0,0 +1,24 @@
+
+
+
+
+
diff --git a/src/lib/components/admin/SettingsForm/index.svelte b/src/lib/components/admin/SettingsForm/index.svelte
index 9e9d847..6aaf1f5 100644
--- a/src/lib/components/admin/SettingsForm/index.svelte
+++ b/src/lib/components/admin/SettingsForm/index.svelte
@@ -3,19 +3,33 @@
import { ProgressRadial } from "@skeletonlabs/skeleton";
import PublicSignup from "./PublicSignup.svelte";
import Suggestions from "./Suggestions.svelte";
- import Smtp from "./SMTP.svelte";
import Claims from "./Claims.svelte";
import Security from "./Security.svelte";
+ import DefaultGroup from "./DefaultGroup.svelte";
+ import Smtp from "./SMTP.svelte";
+
+ type Group = {
+ id: string;
+ name: string;
+ };
interface Props {
config: Config;
+ groups: Group[];
hideActions?: boolean;
saved?: boolean;
sending?: boolean;
sent?: boolean;
}
- let { config = $bindable(), hideActions = false, saved = false, sending = false, sent = false }: Props = $props();
+ let {
+ config = $bindable(),
+ groups = [],
+ hideActions = false,
+ saved = false,
+ sending = false,
+ sent = false
+ }: Props = $props();
let form = $derived($page.form);
@@ -34,6 +48,9 @@
+
+
+
=> {
@@ -79,7 +80,8 @@ export const getConfig = async (groupId?: string, includeSensitive = false): Pro
listMode: (configMap[ConfigKey.LIST_MODE] as ListMode) || "standard",
security: {
passwordStrength: Number(configMap[ConfigKey.SECURITY_PASSWORD_STRENGTH] || 2)
- }
+ },
+ defaultGroup: configMap[ConfigKey.DEFAULT_GROUP]!
};
return config;
@@ -141,6 +143,7 @@ export const writeConfig = async (config: Partial, groupId = GLOBAL) =>
configMap[ConfigKey.CLAIMS_SHOW_NAME] = config?.claims?.showName.toString();
configMap[ConfigKey.LIST_MODE] = config?.listMode;
configMap[ConfigKey.SECURITY_PASSWORD_STRENGTH] = config?.security?.passwordStrength.toString();
+ configMap[ConfigKey.DEFAULT_GROUP] = config?.defaultGroup;
for (const [key, value] of Object.entries(configMap)) {
await client.systemConfig.upsert({
diff --git a/src/lib/validations.ts b/src/lib/validations.ts
index f51d423..4b37218 100644
--- a/src/lib/validations.ts
+++ b/src/lib/validations.ts
@@ -52,7 +52,8 @@ export const settingSchema = z.object({
smtpFromName: z.string().optional(),
claimsShowName: z.coerce.boolean().default(false),
listMode: z.enum(["standard", "registry"]).default("standard"),
- passwordStrength: z.coerce.number().min(-1).max(5).default(2)
+ passwordStrength: z.coerce.number().min(-1).max(5).default(2),
+ defaultGroup: z.string().optional()
});
export const publicListCreateSchema = z.object({
diff --git a/src/routes/admin/groups/[groupId]/members/+page.svelte b/src/routes/admin/groups/[groupId]/members/+page.svelte
index 27d8cbf..47afce0 100644
--- a/src/routes/admin/groups/[groupId]/members/+page.svelte
+++ b/src/routes/admin/groups/[groupId]/members/+page.svelte
@@ -65,6 +65,14 @@
};
const deleteGroup = () => {
+ if (data.config.defaultGroup === $page.params.groupId) {
+ modalStore.trigger({
+ type: "alert",
+ title: "Cannot Delete Default Group",
+ body: "You cannot delete the default group. Please change the default group before deleting this group."
+ });
+ return;
+ }
modalStore.trigger({
type: "confirm",
title: "Delete Group",
diff --git a/src/routes/admin/settings/+page.server.ts b/src/routes/admin/settings/+page.server.ts
index 0d29397..8152c59 100644
--- a/src/routes/admin/settings/+page.server.ts
+++ b/src/routes/admin/settings/+page.server.ts
@@ -1,4 +1,5 @@
import { Role } from "$lib/schema";
+import { client } from "$lib/server/prisma";
import { getConfig, writeConfig } from "$lib/server/config";
import { redirect, error, fail, type Actions } from "@sveltejs/kit";
import type { PageServerLoad } from "./$types";
@@ -16,8 +17,16 @@ export const load: PageServerLoad = async ({ locals }) => {
const config = await getConfig(undefined, true);
+ const groups = await client.group.findMany({
+ select: {
+ id: true,
+ name: true
+ }
+ });
+
return {
- config
+ config,
+ groups
};
};
@@ -82,7 +91,8 @@ const generateConfig = (configData: z.infer) => {
listMode: "standard",
security: {
passwordStrength: configData.passwordStrength
- }
+ },
+ defaultGroup: configData.defaultGroup
};
return newConfig;
diff --git a/src/routes/admin/settings/+page.svelte b/src/routes/admin/settings/+page.svelte
index cfbf8f5..032d92d 100644
--- a/src/routes/admin/settings/+page.svelte
+++ b/src/routes/admin/settings/+page.svelte
@@ -11,6 +11,7 @@
let { data }: Props = $props();
let config = $state(data.config);
+ let groups = $state(data.groups);
let sending = $state(false);
let saved = $state(false);
let sent = $state(false);
@@ -36,5 +37,5 @@
};
}}
>
-
+
diff --git a/src/routes/setup-wizard/step/[step]/GlobalSettingsStep.svelte b/src/routes/setup-wizard/step/[step]/GlobalSettingsStep.svelte
index 30eddf4..173dc22 100644
--- a/src/routes/setup-wizard/step/[step]/GlobalSettingsStep.svelte
+++ b/src/routes/setup-wizard/step/[step]/GlobalSettingsStep.svelte
@@ -5,10 +5,12 @@
import { getContext } from "svelte";
import type { Writable } from "svelte/store";
import type { Props } from "./steps";
+ import type { Group } from "@prisma/client";
let { onSuccess }: Props = $props();
let config: Config = $state($page.data.config);
+ let groups: Group[] = $state($page.data.groups);
let form: HTMLFormElement | undefined = $state();
let sending = $state(false);
let saved = $state(false);
@@ -51,7 +53,7 @@
};
}}
>
-
+
diff --git a/src/routes/signup/+page.server.ts b/src/routes/signup/+page.server.ts
index 8f6aa1f..8efda30 100644
--- a/src/routes/signup/+page.server.ts
+++ b/src/routes/signup/+page.server.ts
@@ -43,6 +43,7 @@ export const load: PageServerLoad = async ({ locals, request }) => {
export const actions: Actions = {
default: async ({ request, cookies }) => {
+ const config = await getConfig();
const formData = Object.fromEntries(await request.formData());
const signupSchema = await getSignupSchema();
const signupData = signupSchema.safeParse(formData);
@@ -79,6 +80,8 @@ export const actions: Actions = {
}
})
)?.id;
+ } else if (config.defaultGroup) {
+ groupId = config.defaultGroup;
}
try {