mirror of
https://github.com/Portabase/portabase.git
synced 2026-07-14 11:16:13 +02:00
fix: toast error message,social legacy
This commit is contained in:
+13
-10
@@ -1,10 +1,10 @@
|
||||
# Environnement
|
||||
# Environment
|
||||
NODE_ENV=development
|
||||
|
||||
# Base de données
|
||||
# Database
|
||||
DATABASE_URL=postgresql://devuser:changeme@localhost:5433/devdb?schema=public
|
||||
|
||||
# Projet
|
||||
# Project
|
||||
PROJECT_NAME="Portabase"
|
||||
PROJECT_DESCRIPTION="Portabase is a powerful database manager"
|
||||
PROJECT_URL=http://localhost:8887
|
||||
@@ -21,11 +21,7 @@ SMTP_FROM=
|
||||
#Port 465 -> secure: true
|
||||
#By default : true
|
||||
|
||||
# Google
|
||||
AUTH_GOOGLE_ID=
|
||||
AUTH_GOOGLE_SECRET=
|
||||
AUTH_GOOGLE_METHOD=
|
||||
|
||||
# OIDC SSO Authentification
|
||||
AUTH_OIDC_ID=""
|
||||
AUTH_OIDC_TITLE=""
|
||||
AUTH_OIDC_DESC=""
|
||||
@@ -40,14 +36,21 @@ AUTH_OIDC_JWKS_ENDPOINT=""
|
||||
AUTH_OIDC_PKCE=true
|
||||
ALLOWED_GROUP="admin"
|
||||
|
||||
# Social OAuth2 Authentification
|
||||
AUTH_SOCIAL_ID=""
|
||||
AUTH_SOCIAL_TITLE=""
|
||||
AUTH_SOCIAL_DESC=""
|
||||
AUTH_SOCIAL_ICON=""
|
||||
AUTH_SOCIAL_CLIENT=""
|
||||
AUTH_SOCIAL_SECRET=""
|
||||
AUTH_SOCIAL_APPLE_APP_BUNDLE_IDENTIFIER=""
|
||||
|
||||
# If true, the user's role will be updated from OIDC claims on every login.
|
||||
# If false, the role is only set when the user is first created.
|
||||
AUTH_SYNC_OIDC_ROLES_ON_LOGIN=true
|
||||
|
||||
AUTH_EMAIL_PASSWORD_ENABLED=true
|
||||
AUTH_SIGNUP_ENABLED=true
|
||||
AUTH_PASSKEY_ENABLED=true
|
||||
|
||||
# Retention
|
||||
RETENTION_CRON="* * * * *"
|
||||
|
||||
|
||||
@@ -22,11 +22,7 @@ export default async function Layout({
|
||||
<div className="flex flex-col items-center justify-center flex-1">
|
||||
<div className="mx-auto w-full max-w-md">
|
||||
<AuthLogoSection />
|
||||
<div className="mt-4">
|
||||
<Suspense>
|
||||
<ErrorLayout>{children}</ErrorLayout>
|
||||
</Suspense>
|
||||
</div>
|
||||
<div className="mt-4">{children}</div>
|
||||
</div>
|
||||
</div>
|
||||
<footer className="mt-8 text-center text-xs text-muted-foreground flex flex-col gap-1">
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { ReactNode, Suspense } from "react";
|
||||
import { ReactNode } from "react";
|
||||
import { redirect } from "next/navigation";
|
||||
|
||||
import { SidebarInset, SidebarProvider } from "@/components/ui/sidebar";
|
||||
@@ -6,7 +6,6 @@ import { AppSidebar } from "@/components/wrappers/dashboard/common/sidebar/app-s
|
||||
import { Header } from "@/features/layout/Header";
|
||||
import { currentUser } from "@/lib/auth/current-user";
|
||||
import { ThemeMetaUpdater } from "@/features/browser/theme-meta-updater";
|
||||
import { ErrorLayout } from "@/components/wrappers/common/error-layout";
|
||||
|
||||
export default async function Layout({ children }: { children: ReactNode }) {
|
||||
const user = await currentUser();
|
||||
@@ -19,11 +18,7 @@ export default async function Layout({ children }: { children: ReactNode }) {
|
||||
<AppSidebar />
|
||||
<SidebarInset>
|
||||
<Header />
|
||||
<Suspense>
|
||||
<ErrorLayout>
|
||||
<main className="h-full">{children}</main>
|
||||
</ErrorLayout>
|
||||
</Suspense>
|
||||
<main className="h-full">{children}</main>
|
||||
</SidebarInset>
|
||||
</div>
|
||||
</SidebarProvider>
|
||||
|
||||
+30
-82
@@ -1,85 +1,33 @@
|
||||
// "use client"
|
||||
//
|
||||
// import {useSearchParams} from "next/navigation"
|
||||
//
|
||||
// enum Error {
|
||||
// Configuration = "Configuration",
|
||||
// }
|
||||
//
|
||||
// const errorMap = {
|
||||
// [Error.Configuration]: (
|
||||
// <p>
|
||||
// There was a problem when trying to authenticate. Please contact us if this
|
||||
// error persists. Unique error code:{" "}
|
||||
// <code className="rounded-sm bg-slate-100 p-1 text-xs">Configuration</code>
|
||||
// </p>
|
||||
// ),
|
||||
// }
|
||||
//
|
||||
// export default function AuthErrorPage() {
|
||||
// const search = useSearchParams()
|
||||
// const error = search.get("error") as Error
|
||||
//
|
||||
// return (
|
||||
// <div className="flex h-screen w-full flex-col items-center justify-center">
|
||||
// <a
|
||||
// href="#"
|
||||
// className="block max-w-sm rounded-lg border border-gray-200 bg-white p-6 text-center shadow-sm hover:bg-gray-100 dark:border-gray-700 dark:bg-gray-800 dark:hover:bg-gray-700"
|
||||
// >
|
||||
// <h5 className="mb-2 flex flex-row items-center justify-center gap-2 text-xl font-bold tracking-tight text-gray-900 dark:text-white">
|
||||
// Something went wrong
|
||||
// </h5>
|
||||
// <div className="font-normal text-gray-700 dark:text-gray-400">
|
||||
// {errorMap[error] || "Please contact us if this error persists."}
|
||||
// </div>
|
||||
// </a>
|
||||
// </div>
|
||||
// )
|
||||
// }
|
||||
"use client"
|
||||
"use client";
|
||||
|
||||
import { useSearchParams } from "next/navigation"
|
||||
import React, { Suspense } from "react"
|
||||
import { Loader2 } from "lucide-react";
|
||||
import { useRouter, useSearchParams } from "next/navigation";
|
||||
import { useEffect } from "react";
|
||||
import { useSession } from "@/lib/auth/auth-client";
|
||||
|
||||
enum Error {
|
||||
Configuration = "Configuration",
|
||||
export default function ErrorPage() {
|
||||
const router = useRouter();
|
||||
const searchParams = useSearchParams();
|
||||
const { data: session, isPending } = useSession();
|
||||
|
||||
useEffect(() => {
|
||||
if (isPending) {
|
||||
return;
|
||||
}
|
||||
|
||||
const error = searchParams.get("error");
|
||||
const params = new URLSearchParams();
|
||||
if (error) {
|
||||
params.set("error", error);
|
||||
}
|
||||
|
||||
const destination = session ? "/dashboard/home" : "/login";
|
||||
router.replace(`${destination}?${params.toString()}`);
|
||||
}, [isPending, session, router, searchParams]);
|
||||
|
||||
return (
|
||||
<div className="flex h-screen w-full items-center justify-center">
|
||||
<Loader2 className="h-8 w-8 animate-spin" />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
const errorMap = {
|
||||
[Error.Configuration]: (
|
||||
<p>
|
||||
There was a problem when trying to authenticate. Please contact us if this
|
||||
error persists. Unique error code:{" "}
|
||||
<code className="rounded-sm bg-slate-100 p-1 text-xs">Configuration</code>
|
||||
</p>
|
||||
),
|
||||
}
|
||||
|
||||
function AuthErrorPageContent() {
|
||||
const search = useSearchParams()
|
||||
const error = search.get("error") as Error
|
||||
|
||||
return (
|
||||
<div className="flex h-screen w-full flex-col items-center justify-center">
|
||||
<a
|
||||
href="#"
|
||||
className="block max-w-sm rounded-lg border border-gray-200 bg-white p-6 text-center shadow-sm hover:bg-gray-100 dark:border-gray-700 dark:bg-gray-800 dark:hover:bg-gray-700"
|
||||
>
|
||||
<h5 className="mb-2 flex flex-row items-center justify-center gap-2 text-xl font-bold tracking-tight text-gray-900 dark:text-white">
|
||||
Something went wrong
|
||||
</h5>
|
||||
<div className="font-normal text-gray-700 dark:text-gray-400">
|
||||
{errorMap[error] || "Please contact us if this error persists."}
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default function AuthErrorPage() {
|
||||
return (
|
||||
<Suspense fallback={<div>Loading...</div>}>
|
||||
<AuthErrorPageContent />
|
||||
</Suspense>
|
||||
)
|
||||
}
|
||||
+32
-28
@@ -1,38 +1,42 @@
|
||||
import React from "react";
|
||||
import type {Metadata} from "next";
|
||||
import type { Metadata } from "next";
|
||||
import type React from "react";
|
||||
import "./globals.css";
|
||||
import {Providers} from "./providers";
|
||||
import {cn} from "@/lib/utils";
|
||||
import {ConsoleSilencer} from "@/components/wrappers/common/console-silencer";
|
||||
import {author, geistMono, poppins} from "@/fonts/fonts";
|
||||
import { ConsoleSilencer } from "@/components/wrappers/common/console-silencer";
|
||||
import { author, geistMono, poppins } from "@/fonts/fonts";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { Providers } from "./providers";
|
||||
|
||||
const title = process.env.PROJECT_NAME ?? "App Title";
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: {
|
||||
default: title,
|
||||
template: `%s - ${title}`
|
||||
},
|
||||
description: process.env.PROJECT_DESCRIPTION ?? undefined,
|
||||
title: {
|
||||
default: title,
|
||||
template: `%s - ${title}`,
|
||||
},
|
||||
description: process.env.PROJECT_DESCRIPTION ?? undefined,
|
||||
};
|
||||
|
||||
export default async function RootLayout({
|
||||
children,
|
||||
}: Readonly<{
|
||||
children: React.ReactNode;
|
||||
children,
|
||||
}: Readonly<{
|
||||
children: React.ReactNode;
|
||||
}>) {
|
||||
|
||||
return (
|
||||
<html lang="en" suppressHydrationWarning>
|
||||
<head>
|
||||
<meta name="apple-mobile-web-app-title" content={title}/>
|
||||
</head>
|
||||
<body className={cn(poppins.variable, author.variable, geistMono.variable, "font-sans h-full")}>
|
||||
<ConsoleSilencer/>
|
||||
<Providers>
|
||||
{children}
|
||||
</Providers>
|
||||
</body>
|
||||
</html>
|
||||
);
|
||||
return (
|
||||
<html lang="en" suppressHydrationWarning>
|
||||
<head>
|
||||
<meta name="apple-mobile-web-app-title" content={title} />
|
||||
</head>
|
||||
<body
|
||||
className={cn(
|
||||
poppins.variable,
|
||||
author.variable,
|
||||
geistMono.variable,
|
||||
"font-sans h-full",
|
||||
)}
|
||||
>
|
||||
<ConsoleSilencer />
|
||||
<Providers>{children}</Providers>
|
||||
</body>
|
||||
</html>
|
||||
);
|
||||
}
|
||||
|
||||
+14
-10
@@ -1,15 +1,19 @@
|
||||
import BackButton from "@/components/wrappers/common/button/back-button";
|
||||
|
||||
export default async function NotFound() {
|
||||
return(
|
||||
<div className="flex items-center min-h-screen px-4 py-12 sm:px-6 md:px-8 lg:px-12 xl:px-16">
|
||||
<div className="w-full space-y-6 text-center">
|
||||
<div className="space-y-3">
|
||||
<h1 className="scroll-m-20 text-4xl font-extrabold tracking-tight lg:text-5xl">Not found</h1>
|
||||
<p className="leading-7 [&:not(:first-child)]:mt-6">The content you are trying to view is not available.</p>
|
||||
</div>
|
||||
<BackButton>Go home</BackButton>
|
||||
</div>
|
||||
return (
|
||||
<div className="flex items-center min-h-screen px-4 py-12 sm:px-6 md:px-8 lg:px-12 xl:px-16">
|
||||
<div className="w-full space-y-6 text-center">
|
||||
<div className="space-y-3">
|
||||
<h1 className="scroll-m-20 text-4xl font-extrabold tracking-tight lg:text-5xl">
|
||||
Not found
|
||||
</h1>
|
||||
<p className="leading-7 not-first:mt-6">
|
||||
The content you are trying to view is not available.
|
||||
</p>
|
||||
</div>
|
||||
)
|
||||
<BackButton>Go home</BackButton>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
+19
-21
@@ -1,30 +1,28 @@
|
||||
"use client";
|
||||
|
||||
import {PropsWithChildren, Suspense} from "react";
|
||||
import {ThemeProvider} from "@/features/theme/theme-provider";
|
||||
|
||||
import {Toaster} from "@/components/ui/sonner";
|
||||
import {QueryClient, QueryClientProvider} from "@tanstack/react-query";
|
||||
import {ThemeMetaUpdaterRoot} from "@/features/browser/theme-meta-updater-root";
|
||||
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
||||
import { type PropsWithChildren, Suspense } from "react";
|
||||
|
||||
import { Toaster } from "@/components/ui/sonner";
|
||||
import { ErrorLayout } from "@/components/wrappers/common/error-layout";
|
||||
import { ThemeMetaUpdaterRoot } from "@/features/browser/theme-meta-updater-root";
|
||||
import { ThemeProvider } from "@/features/theme/theme-provider";
|
||||
|
||||
export type ProviderProps = PropsWithChildren<{}>;
|
||||
const queryClient = new QueryClient();
|
||||
|
||||
export const Providers = (props: ProviderProps) => {
|
||||
return (
|
||||
<Suspense fallback={null}>
|
||||
<ThemeProvider
|
||||
attribute="class"
|
||||
defaultTheme="system"
|
||||
enableSystem
|
||||
>
|
||||
<ThemeMetaUpdaterRoot/>
|
||||
<QueryClientProvider client={queryClient}>
|
||||
<Toaster/>
|
||||
{props.children}
|
||||
</QueryClientProvider>
|
||||
</ThemeProvider>
|
||||
</Suspense>
|
||||
);
|
||||
return (
|
||||
<Suspense fallback={null}>
|
||||
<ThemeProvider attribute="class" defaultTheme="system" enableSystem>
|
||||
<ThemeMetaUpdaterRoot />
|
||||
<QueryClientProvider client={queryClient}>
|
||||
<ErrorLayout>
|
||||
<Toaster />
|
||||
{props.children}
|
||||
</ErrorLayout>
|
||||
</QueryClientProvider>
|
||||
</ThemeProvider>
|
||||
</Suspense>
|
||||
);
|
||||
};
|
||||
|
||||
+7
-2
@@ -29,7 +29,6 @@ export const env = createEnv({
|
||||
|
||||
AUTH_GOOGLE_ID: z.string().optional(),
|
||||
AUTH_GOOGLE_SECRET: z.string().optional(),
|
||||
AUTH_GOOGLE_METHOD: z.boolean().default(false),
|
||||
|
||||
AUTH_GITHUB_ID: z.string().optional(),
|
||||
AUTH_GITHUB_SECRET: z.string().optional(),
|
||||
@@ -69,7 +68,7 @@ export const env = createEnv({
|
||||
|
||||
AUTH_SYNC_OIDC_ROLES_ON_LOGIN: z.enum(["true", "false"]).default("true"),
|
||||
AUTH_ROLE_MAP: z.string().optional(),
|
||||
AUTH_DEFAULT_ROLE: z.string().optional(),
|
||||
AUTH_DEFAULT_ROLE: z.string().optional().default("pending"),
|
||||
AUTH_ALLOW_LINKING: z.enum(["true", "false"]).default("false"),
|
||||
AUTH_ALLOW_UNLINKING: z.enum(["true", "false"]).default("false"),
|
||||
|
||||
@@ -110,6 +109,12 @@ export const env = createEnv({
|
||||
AUTH_OIDC_JWKS_ENDPOINT: process.env.AUTH_OIDC_JWKS_ENDPOINT,
|
||||
AUTH_OIDC_PKCE: process.env.AUTH_OIDC_PKCE,
|
||||
|
||||
AUTH_GOOGLE_ID: process.env.AUTH_GOOGLE_ID,
|
||||
AUTH_GOOGLE_SECRET: process.env.AUTH_GOOGLE_SECRET,
|
||||
|
||||
AUTH_GITHUB_ID: process.env.AUTH_GITHUB_ID,
|
||||
AUTH_GITHUB_SECRET: process.env.AUTH_GITHUB_SECRET,
|
||||
|
||||
AUTH_SOCIAL_ID: process.env.AUTH_SOCIAL_ID,
|
||||
AUTH_SOCIAL_TITLE: process.env.AUTH_SOCIAL_TITLE,
|
||||
AUTH_SOCIAL_DESC: process.env.AUTH_SOCIAL_DESC,
|
||||
|
||||
@@ -45,7 +45,7 @@ const oidcProviders = getOidcProviders();
|
||||
|
||||
export const auth = betterAuth({
|
||||
onAPIError: {
|
||||
errorURL: "/dashboard/home",
|
||||
errorURL: "/error",
|
||||
onError: (error, ctx) => {
|
||||
//todo: capture errors in a monitoring service
|
||||
},
|
||||
|
||||
@@ -56,6 +56,38 @@ function getProviderIcon(providerId: string, envIcon?: string): string {
|
||||
export function getOAuthProviders(): OAuthProvider[] {
|
||||
const providers: OAuthProvider[] = [];
|
||||
|
||||
if (env.AUTH_GOOGLE_ID && env.AUTH_GOOGLE_SECRET) {
|
||||
providers.push({
|
||||
id: "google",
|
||||
title: "Google",
|
||||
description: "Sign in with your Google account.",
|
||||
icon: getProviderIcon("google"),
|
||||
client: env.AUTH_GOOGLE_ID,
|
||||
secret: env.AUTH_GOOGLE_SECRET,
|
||||
allowedGroup: env.ALLOWED_GROUP,
|
||||
roleMap: env.AUTH_ROLE_MAP ?? undefined,
|
||||
defaultRole: env.AUTH_DEFAULT_ROLE ?? "pending",
|
||||
allowLinking: env.AUTH_ALLOW_LINKING !== "false",
|
||||
allowUnlinking: env.AUTH_ALLOW_UNLINKING !== "false",
|
||||
});
|
||||
}
|
||||
|
||||
if (env.AUTH_GITHUB_ID && env.AUTH_GITHUB_SECRET) {
|
||||
providers.push({
|
||||
id: "github",
|
||||
title: "GitHub",
|
||||
description: "Sign in with your GitHub account.",
|
||||
icon: getProviderIcon("github"),
|
||||
client: env.AUTH_GITHUB_ID,
|
||||
secret: env.AUTH_GITHUB_SECRET,
|
||||
allowedGroup: env.ALLOWED_GROUP,
|
||||
roleMap: env.AUTH_ROLE_MAP,
|
||||
defaultRole: env.AUTH_DEFAULT_ROLE,
|
||||
allowLinking: env.AUTH_ALLOW_LINKING !== "false",
|
||||
allowUnlinking: env.AUTH_ALLOW_UNLINKING !== "false",
|
||||
});
|
||||
}
|
||||
|
||||
if (env.AUTH_SOCIAL_CLIENT && env.AUTH_SOCIAL_ID) {
|
||||
providers.push({
|
||||
id: env.AUTH_SOCIAL_ID,
|
||||
|
||||
+118
-107
@@ -1,127 +1,138 @@
|
||||
import {env} from "@/env.mjs";
|
||||
import {db, makeMigration} from "@/db";
|
||||
import {eq} from "drizzle-orm";
|
||||
import { env } from "@/env.mjs";
|
||||
import { db, makeMigration } from "@/db";
|
||||
import { eq } from "drizzle-orm";
|
||||
import * as drizzleDb from "@/db";
|
||||
import {cleaningJob, retentionJob} from "@/lib/tasks";
|
||||
import {generateRSAKeys, getOrCreateMasterKey} from "@/utils/rsa-keys";
|
||||
import {StorageProviderKind} from "@/features/storages/types";
|
||||
|
||||
import { cleaningJob, retentionJob } from "@/lib/tasks";
|
||||
import { generateRSAKeys, getOrCreateMasterKey } from "@/utils/rsa-keys";
|
||||
import { StorageProviderKind } from "@/features/storages/types";
|
||||
|
||||
export async function init() {
|
||||
consoleAscii();
|
||||
console.log("====Init Functions====");
|
||||
await getOrCreateMasterKey();
|
||||
await generateRSAKeys();
|
||||
await makeMigration();
|
||||
await createDefaultOrganization();
|
||||
await createSettingsIfNotExist()
|
||||
console.log("====Initialization completed====");
|
||||
await setupCronJobs()
|
||||
await setupCleaningJobs()
|
||||
consoleAscii();
|
||||
console.log("====Init Functions====");
|
||||
await getOrCreateMasterKey();
|
||||
await generateRSAKeys();
|
||||
await makeMigration();
|
||||
await createDefaultOrganization();
|
||||
await createSettingsIfNotExist();
|
||||
console.log("====Initialization completed====");
|
||||
await setupCronJobs();
|
||||
await setupCleaningJobs();
|
||||
|
||||
if (
|
||||
(env.AUTH_GOOGLE_ID && env.AUTH_GOOGLE_SECRET) ||
|
||||
(env.AUTH_GITHUB_ID && env.AUTH_GITHUB_SECRET)
|
||||
) {
|
||||
console.warn(
|
||||
"[Deprecation Warning] You have set up OAuth credentials in your environment variables, but the format is now different. Please update your environment variables to use the new format. For example, if you were using AUTH_GOOGLE_ID and AUTH_GOOGLE_SECRET, you should now use AUTH_GOOGLE_CLIENT and AUTH_GOOGLE_SECRET. Please refer to the documentation for more details.",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
async function setupCronJobs() {
|
||||
console.log("==== Setting up Cron Jobs ====");
|
||||
retentionJob.start();
|
||||
console.log("==== Cron job started ====");
|
||||
console.log("==== Setting up Cron Jobs ====");
|
||||
retentionJob.start();
|
||||
console.log("==== Cron job started ====");
|
||||
}
|
||||
|
||||
async function setupCleaningJobs() {
|
||||
console.log("==== Setting up Cleaning Jobs ====");
|
||||
cleaningJob.start();
|
||||
console.log("==== Cleaning job started ====");
|
||||
console.log("==== Setting up Cleaning Jobs ====");
|
||||
cleaningJob.start();
|
||||
console.log("==== Cleaning job started ====");
|
||||
}
|
||||
|
||||
async function createSettingsIfNotExist() {
|
||||
await db.transaction(async (tx) => {
|
||||
const systemSettingsValues = {
|
||||
name: "system",
|
||||
smtpPassword: env.SMTP_PASSWORD ?? null,
|
||||
smtpFrom: env.SMTP_FROM ?? null,
|
||||
smtpHost: env.SMTP_HOST ?? null,
|
||||
smtpPort: env.SMTP_PORT ?? null,
|
||||
smtpUser: env.SMTP_USER ?? null,
|
||||
smtpSecure: env.SMTP_SECURE ?? false,
|
||||
};
|
||||
|
||||
const [systemSetting] = await tx
|
||||
.select()
|
||||
.from(drizzleDb.schemas.setting)
|
||||
.where(eq(drizzleDb.schemas.setting.name, "system"))
|
||||
.limit(1);
|
||||
|
||||
const [finalSystemSetting] = systemSetting
|
||||
? await tx
|
||||
.update(drizzleDb.schemas.setting)
|
||||
.set(systemSettingsValues)
|
||||
.where(eq(drizzleDb.schemas.setting.name, "system"))
|
||||
.returning()
|
||||
: await tx
|
||||
.insert(drizzleDb.schemas.setting)
|
||||
.values(systemSettingsValues)
|
||||
.returning();
|
||||
|
||||
|
||||
const localStorageValues = {
|
||||
provider: "local" as StorageProviderKind,
|
||||
enabled: true,
|
||||
name: "System",
|
||||
config: {},
|
||||
};
|
||||
|
||||
const [existingLocalStorage] = await tx
|
||||
.select()
|
||||
.from(drizzleDb.schemas.storageChannel)
|
||||
.where(eq(drizzleDb.schemas.storageChannel.provider, "local"))
|
||||
.limit(1);
|
||||
|
||||
const [localStorage] = existingLocalStorage
|
||||
? await tx
|
||||
.update(drizzleDb.schemas.storageChannel)
|
||||
.set(localStorageValues)
|
||||
.where(eq(drizzleDb.schemas.storageChannel.provider, "local"))
|
||||
.returning()
|
||||
: await tx
|
||||
.insert(drizzleDb.schemas.storageChannel)
|
||||
.values(localStorageValues)
|
||||
.returning();
|
||||
|
||||
|
||||
if (!finalSystemSetting.defaultStorageChannelId) {
|
||||
await tx
|
||||
.update(drizzleDb.schemas.setting)
|
||||
.set({defaultStorageChannelId: localStorage.id})
|
||||
.where(eq(drizzleDb.schemas.setting.id, finalSystemSetting.id));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
async function createDefaultOrganization() {
|
||||
const defaultOrganizationConf = {
|
||||
slug: "default",
|
||||
name: "Default Organization",
|
||||
createdAt: new Date(),
|
||||
await db.transaction(async (tx) => {
|
||||
const systemSettingsValues = {
|
||||
name: "system",
|
||||
smtpPassword: env.SMTP_PASSWORD ?? null,
|
||||
smtpFrom: env.SMTP_FROM ?? null,
|
||||
smtpHost: env.SMTP_HOST ?? null,
|
||||
smtpPort: env.SMTP_PORT ?? null,
|
||||
smtpUser: env.SMTP_USER ?? null,
|
||||
smtpSecure: env.SMTP_SECURE ?? false,
|
||||
};
|
||||
|
||||
const [existing] = await db.select().from(drizzleDb.schemas.organization).where(eq(drizzleDb.schemas.organization.slug, "default")).limit(1);
|
||||
const [systemSetting] = await tx
|
||||
.select()
|
||||
.from(drizzleDb.schemas.setting)
|
||||
.where(eq(drizzleDb.schemas.setting.name, "system"))
|
||||
.limit(1);
|
||||
|
||||
if (!existing) {
|
||||
console.log("==== Creating default Organization... ====");
|
||||
await db.insert(drizzleDb.schemas.organization).values(defaultOrganizationConf);
|
||||
const [finalSystemSetting] = systemSetting
|
||||
? await tx
|
||||
.update(drizzleDb.schemas.setting)
|
||||
.set(systemSettingsValues)
|
||||
.where(eq(drizzleDb.schemas.setting.name, "system"))
|
||||
.returning()
|
||||
: await tx
|
||||
.insert(drizzleDb.schemas.setting)
|
||||
.values(systemSettingsValues)
|
||||
.returning();
|
||||
|
||||
const localStorageValues = {
|
||||
provider: "local" as StorageProviderKind,
|
||||
enabled: true,
|
||||
name: "System",
|
||||
config: {},
|
||||
};
|
||||
|
||||
const [existingLocalStorage] = await tx
|
||||
.select()
|
||||
.from(drizzleDb.schemas.storageChannel)
|
||||
.where(eq(drizzleDb.schemas.storageChannel.provider, "local"))
|
||||
.limit(1);
|
||||
|
||||
const [localStorage] = existingLocalStorage
|
||||
? await tx
|
||||
.update(drizzleDb.schemas.storageChannel)
|
||||
.set(localStorageValues)
|
||||
.where(eq(drizzleDb.schemas.storageChannel.provider, "local"))
|
||||
.returning()
|
||||
: await tx
|
||||
.insert(drizzleDb.schemas.storageChannel)
|
||||
.values(localStorageValues)
|
||||
.returning();
|
||||
|
||||
if (!finalSystemSetting.defaultStorageChannelId) {
|
||||
await tx
|
||||
.update(drizzleDb.schemas.setting)
|
||||
.set({ defaultStorageChannelId: localStorage.id })
|
||||
.where(eq(drizzleDb.schemas.setting.id, finalSystemSetting.id));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async function createDefaultOrganization() {
|
||||
const defaultOrganizationConf = {
|
||||
slug: "default",
|
||||
name: "Default Organization",
|
||||
createdAt: new Date(),
|
||||
};
|
||||
|
||||
const [existing] = await db
|
||||
.select()
|
||||
.from(drizzleDb.schemas.organization)
|
||||
.where(eq(drizzleDb.schemas.organization.slug, "default"))
|
||||
.limit(1);
|
||||
|
||||
if (!existing) {
|
||||
console.log("==== Creating default Organization... ====");
|
||||
await db
|
||||
.insert(drizzleDb.schemas.organization)
|
||||
.values(defaultOrganizationConf);
|
||||
}
|
||||
}
|
||||
|
||||
function consoleAscii() {
|
||||
console.log(
|
||||
" \n" +
|
||||
" ____ __ __ \n" +
|
||||
" / __ \\____ _____/ /_____ _/ /_ ____ _________ \n" +
|
||||
" / /_/ / __ \\/ ___/ __/ __ / __ \\/ __ / ___/ _ \\ \n" +
|
||||
" / ____/ /_/ / / / /_/ /_/ / /_/ / /_/ (__ ) __/ \n" +
|
||||
" /_/ \\____/_/ \\__/\\__,_/_.___/\\__,_/____/\\___/ \n" +
|
||||
" \n" +
|
||||
` Community Edition v${env.NEXT_PUBLIC_PROJECT_VERSION} \n ` +
|
||||
" \n"
|
||||
)
|
||||
console.log(
|
||||
" \n" +
|
||||
" ____ __ __ \n" +
|
||||
" / __ \\____ _____/ /_____ _/ /_ ____ _________ \n" +
|
||||
" / /_/ / __ \\/ ___/ __/ __ / __ \\/ __ / ___/ _ \\ \n" +
|
||||
" / ____/ /_/ / / / /_/ /_/ / /_/ / /_/ (__ ) __/ \n" +
|
||||
" /_/ \\____/_/ \\__/\\__,_/_.___/\\__,_/____/\\___/ \n" +
|
||||
" \n" +
|
||||
` Community Edition v${env.NEXT_PUBLIC_PROJECT_VERSION} \n ` +
|
||||
" \n",
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user