diff --git a/.gitignore b/.gitignore
index 74154c00..2f3b58c0 100755
--- a/.gitignore
+++ b/.gitignore
@@ -23,6 +23,7 @@
# misc
.DS_Store
*.pem
+.idea
# debug
npm-debug.log*
diff --git a/prisma/migrations/20250607030453_discord_whitelist/migration.sql b/prisma/migrations/20250607030453_discord_whitelist/migration.sql
new file mode 100644
index 00000000..155f2a6d
--- /dev/null
+++ b/prisma/migrations/20250607030453_discord_whitelist/migration.sql
@@ -0,0 +1,2 @@
+-- AlterTable
+ALTER TABLE "Zipline" ADD COLUMN "oauthDiscordWhitelistIds" TEXT[] DEFAULT ARRAY[]::TEXT[];
diff --git a/prisma/schema.prisma b/prisma/schema.prisma
index 7390fd6c..4dd6baa6 100755
--- a/prisma/schema.prisma
+++ b/prisma/schema.prisma
@@ -82,6 +82,7 @@ model Zipline {
oauthDiscordClientId String?
oauthDiscordClientSecret String?
oauthDiscordRedirectUri String?
+ oauthDiscordWhitelistIds String[] @default([])
oauthGoogleClientId String?
oauthGoogleClientSecret String?
diff --git a/src/components/pages/serverSettings/parts/ServerSettingsOauth.tsx b/src/components/pages/serverSettings/parts/ServerSettingsOauth.tsx
index bffd4f3c..54ceb6f2 100644
--- a/src/components/pages/serverSettings/parts/ServerSettingsOauth.tsx
+++ b/src/components/pages/serverSettings/parts/ServerSettingsOauth.tsx
@@ -30,6 +30,7 @@ export default function ServerSettingsOauth({
oauthDiscordClientId: '',
oauthDiscordClientSecret: '',
oauthDiscordRedirectUri: '',
+ oauthDiscordWhitelistIds: '',
oauthGoogleClientId: '',
oauthGoogleClientSecret: '',
@@ -50,7 +51,7 @@ export default function ServerSettingsOauth({
const onSubmit = async (values: typeof form.values) => {
for (const key in values) {
- if (!['oauthBypassLocalLogin', 'oauthLoginOnly'].includes(key)) {
+ if (!['oauthBypassLocalLogin', 'oauthLoginOnly', 'oauthDiscordWhitelistIds'].includes(key)) {
if ((values[key as keyof typeof form.values] as string)?.trim() === '') {
// @ts-ignore
values[key as keyof typeof form.values] = null;
@@ -61,6 +62,16 @@ export default function ServerSettingsOauth({
)?.trim();
}
}
+
+ if (key === 'oauthDiscordWhitelistIds') {
+ if (Array.isArray(values['oauthDiscordWhitelistIds'])) continue;
+
+ // @ts-ignore
+ values['oauthDiscordWhitelistIds'] = (values['oauthDiscordWhitelistIds'] as string)
+ .split(',')
+ .map((id) => id.trim())
+ .filter((id) => id !== '');
+ }
}
return settingsOnSubmit(router, form)(values);
@@ -76,6 +87,9 @@ export default function ServerSettingsOauth({
oauthDiscordClientId: data?.oauthDiscordClientId ?? '',
oauthDiscordClientSecret: data?.oauthDiscordClientSecret ?? '',
oauthDiscordRedirectUri: data?.oauthDiscordRedirectUri ?? '',
+ oauthDiscordWhitelistIds: data?.oauthDiscordWhitelistIds
+ ? data?.oauthDiscordWhitelistIds.join(', ')
+ : '',
oauthGoogleClientId: data?.oauthGoogleClientId ?? '',
oauthGoogleClientSecret: data?.oauthGoogleClientSecret ?? '',
@@ -129,6 +143,11 @@ export default function ServerSettingsOauth({
+
/^\d+$/.test(s), 'Discord ID must be a number')),
+ z
+ .string()
+ .refine((s) => s === '' || /^\d+(,\d+)*$/.test(s), 'Discord IDs must be comma-separated'),
+ ])
+ .transform((value) =>
+ typeof value === 'string' ? value.split(',').map((id) => id.trim()) : value,
+ ),
oauthGoogleClientId: z.string().nullable(),
oauthGoogleClientSecret: z.string().nullable(),