Compare commits
3 Commits
fix/missin
...
v0.4.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ea92dcd2ed | ||
|
|
d51600aba8 | ||
|
|
c3ed2e5e7f |
61
README.md
61
README.md
@@ -138,36 +138,37 @@ pnpm dev
|
|||||||
|
|
||||||
## Environment Variables 🔐
|
## Environment Variables 🔐
|
||||||
|
|
||||||
| Variable | Description | Required | Example |
|
| Variable | Description | Required | Example |
|
||||||
| -------------------------------- | -------------------------------------------------------- | ------------------ | --------------------------------------------- |
|
| ----------------------------------------- | -------------------------------------------------------- | ------------------------ | --------------------------------------------- |
|
||||||
| `POSTGRES_URL` | PostgreSQL connection URL | To use external database | `postgres://user:pass@localhost:5432/db` |
|
| `POSTGRES_URL` | PostgreSQL connection URL | To use external database | `postgres://user:pass@localhost:5432/db` |
|
||||||
| `EMAIL_FROM` | Sender email address | For Email | `"Kan <hello@mail.kan.bn>"` |
|
| `EMAIL_FROM` | Sender email address | For Email | `"Kan <hello@mail.kan.bn>"` |
|
||||||
| `SMTP_HOST` | SMTP server hostname | For Email | `smtp.resend.com` |
|
| `SMTP_HOST` | SMTP server hostname | For Email | `smtp.resend.com` |
|
||||||
| `SMTP_PORT` | SMTP server port | For Email | `465` |
|
| `SMTP_PORT` | SMTP server port | For Email | `465` |
|
||||||
| `SMTP_USER` | SMTP username/email | No | `resend` |
|
| `SMTP_USER` | SMTP username/email | No | `resend` |
|
||||||
| `SMTP_PASSWORD` | SMTP password/token | No | `re_xxxx` |
|
| `SMTP_PASSWORD` | SMTP password/token | No | `re_xxxx` |
|
||||||
| `SMTP_SECURE` | Use secure SMTP connection (defaults to true if not set) | For Email | `true` |
|
| `SMTP_SECURE` | Use secure SMTP connection (defaults to true if not set) | For Email | `true` |
|
||||||
| `NEXT_PUBLIC_BASE_URL` | Base URL of your installation | Yes | `http://localhost:3000` |
|
| `NEXT_PUBLIC_BASE_URL` | Base URL of your installation | Yes | `http://localhost:3000` |
|
||||||
| `BETTER_AUTH_SECRET` | Auth encryption secret | Yes | Random 32+ char string |
|
| `BETTER_AUTH_SECRET` | Auth encryption secret | Yes | Random 32+ char string |
|
||||||
| `BETTER_AUTH_TRUSTED_ORIGINS` | Allowed callback origins | No | `http://localhost:3000,http://localhost:3001` |
|
| `BETTER_AUTH_TRUSTED_ORIGINS` | Allowed callback origins | No | `http://localhost:3000,http://localhost:3001` |
|
||||||
| `GOOGLE_CLIENT_ID` | Google OAuth client ID | For Google login | `xxx.apps.googleusercontent.com` |
|
| `GOOGLE_CLIENT_ID` | Google OAuth client ID | For Google login | `xxx.apps.googleusercontent.com` |
|
||||||
| `GOOGLE_CLIENT_SECRET` | Google OAuth client secret | For Google login | `xxx` |
|
| `GOOGLE_CLIENT_SECRET` | Google OAuth client secret | For Google login | `xxx` |
|
||||||
| `DISCORD_CLIENT_ID` | Discord OAuth client ID | For Discord login | `xxx` |
|
| `DISCORD_CLIENT_ID` | Discord OAuth client ID | For Discord login | `xxx` |
|
||||||
| `DISCORD_CLIENT_SECRET` | Discord OAuth client secret | For Discord login | `xxx` |
|
| `DISCORD_CLIENT_SECRET` | Discord OAuth client secret | For Discord login | `xxx` |
|
||||||
| `GITHUB_CLIENT_ID` | GitHub OAuth client ID | For GitHub login | `xxx` |
|
| `GITHUB_CLIENT_ID` | GitHub OAuth client ID | For GitHub login | `xxx` |
|
||||||
| `GITHUB_CLIENT_SECRET` | GitHub OAuth client secret | For GitHub login | `xxx` |
|
| `GITHUB_CLIENT_SECRET` | GitHub OAuth client secret | For GitHub login | `xxx` |
|
||||||
| `TRELLO_APP_API_KEY` | Trello app API key | For Trello import | `xxx` |
|
| `TRELLO_APP_API_KEY` | Trello app API key | For Trello import | `xxx` |
|
||||||
| `TRELLO_APP_API_SECRET` | Trello app API secret | For Trello import | `xxx` |
|
| `TRELLO_APP_API_SECRET` | Trello app API secret | For Trello import | `xxx` |
|
||||||
| `S3_REGION` | S3 storage region | For file uploads | `WEUR` |
|
| `S3_REGION` | S3 storage region | For file uploads | `WEUR` |
|
||||||
| `S3_ENDPOINT` | S3 endpoint URL | For file uploads | `https://xxx.r2.cloudflarestorage.com` |
|
| `S3_ENDPOINT` | S3 endpoint URL | For file uploads | `https://xxx.r2.cloudflarestorage.com` |
|
||||||
| `S3_ACCESS_KEY_ID` | S3 access key | For file uploads | `xxx` |
|
| `S3_ACCESS_KEY_ID` | S3 access key | For file uploads | `xxx` |
|
||||||
| `S3_SECRET_ACCESS_KEY` | S3 secret key | For file uploads | `xxx` |
|
| `S3_SECRET_ACCESS_KEY` | S3 secret key | For file uploads | `xxx` |
|
||||||
| `S3_FORCE_PATH_STYLE` | Use path-style URLs for S3 | For file uploads | `true` |
|
| `S3_FORCE_PATH_STYLE` | Use path-style URLs for S3 | For file uploads | `true` |
|
||||||
| `NEXT_PUBLIC_STORAGE_URL` | Storage service URL | For file uploads | `https://storage.kanbn.com` |
|
| `NEXT_PUBLIC_STORAGE_URL` | Storage service URL | For file uploads | `https://storage.kanbn.com` |
|
||||||
| `NEXT_PUBLIC_STORAGE_DOMAIN` | Storage domain name | For file uploads | `kanbn.com` |
|
| `NEXT_PUBLIC_STORAGE_DOMAIN` | Storage domain name | For file uploads | `kanbn.com` |
|
||||||
| `NEXT_PUBLIC_AVATAR_BUCKET_NAME` | S3 bucket name for avatars | For file uploads | `avatars` |
|
| `NEXT_PUBLIC_AVATAR_BUCKET_NAME` | S3 bucket name for avatars | For file uploads | `avatars` |
|
||||||
| `NEXT_PUBLIC_ALLOW_CREDENTIALS` | Allow email & password login | For authentication | `true` |
|
| `NEXT_PUBLIC_ALLOW_CREDENTIALS` | Allow email & password login | For authentication | `true` |
|
||||||
| `NEXT_PUBLIC_DISABLE_SIGN_UP` | Disable sign up | For authentication | `false` |
|
| `NEXT_PUBLIC_DISABLE_SIGN_UP` | Disable sign up | For authentication | `false` |
|
||||||
|
| `NEXT_PUBLIC_WHITE_LABEL_HIDE_POWERED_BY` | Hide “Powered by kan.bn” on public boards (self-host) | For white labelling | `true` |
|
||||||
|
|
||||||
See `.env.example` for a complete list of supported environment variables.
|
See `.env.example` for a complete list of supported environment variables.
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ export const env = createEnv({
|
|||||||
s.split(",").every((l) => z.string().url().safeParse(l).success),
|
s.split(",").every((l) => z.string().url().safeParse(l).success),
|
||||||
)
|
)
|
||||||
.optional(),
|
.optional(),
|
||||||
POSTGRES_URL: z.string().url().optional().or(z.literal('')),
|
POSTGRES_URL: z.string().url().optional().or(z.literal("")),
|
||||||
TRELLO_APP_API_KEY: z.string().optional(),
|
TRELLO_APP_API_KEY: z.string().optional(),
|
||||||
TRELLO_APP_SECRET: z.string().optional(),
|
TRELLO_APP_SECRET: z.string().optional(),
|
||||||
STRIPE_SECRET_KEY: z.string().optional(),
|
STRIPE_SECRET_KEY: z.string().optional(),
|
||||||
@@ -101,6 +101,13 @@ export const env = createEnv({
|
|||||||
(s) => !s || s.toLowerCase() === "true" || s.toLowerCase() === "false",
|
(s) => !s || s.toLowerCase() === "true" || s.toLowerCase() === "false",
|
||||||
)
|
)
|
||||||
.optional(),
|
.optional(),
|
||||||
|
NEXT_PUBLIC_WHITE_LABEL_HIDE_POWERED_BY: z
|
||||||
|
.string()
|
||||||
|
.transform((s) => (s === "" ? undefined : s))
|
||||||
|
.refine(
|
||||||
|
(s) => !s || s.toLowerCase() === "true" || s.toLowerCase() === "false",
|
||||||
|
)
|
||||||
|
.optional(),
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* Destructure all variables from `process.env` to make sure they aren't tree-shaken away.
|
* Destructure all variables from `process.env` to make sure they aren't tree-shaken away.
|
||||||
@@ -119,6 +126,8 @@ export const env = createEnv({
|
|||||||
NEXT_PUBLIC_DISABLE_SIGN_UP: process.env.NEXT_PUBLIC_DISABLE_SIGN_UP,
|
NEXT_PUBLIC_DISABLE_SIGN_UP: process.env.NEXT_PUBLIC_DISABLE_SIGN_UP,
|
||||||
NEXT_PUBLIC_USE_STANDALONE_OUTPUT:
|
NEXT_PUBLIC_USE_STANDALONE_OUTPUT:
|
||||||
process.env.NEXT_PUBLIC_USE_STANDALONE_OUTPUT,
|
process.env.NEXT_PUBLIC_USE_STANDALONE_OUTPUT,
|
||||||
|
NEXT_PUBLIC_WHITE_LABEL_HIDE_POWERED_BY:
|
||||||
|
process.env.NEXT_PUBLIC_WHITE_LABEL_HIDE_POWERED_BY,
|
||||||
},
|
},
|
||||||
skipValidation:
|
skipValidation:
|
||||||
!!process.env.CI || process.env.npm_lifecycle_event === "lint",
|
!!process.env.CI || process.env.npm_lifecycle_event === "lint",
|
||||||
|
|||||||
@@ -29,7 +29,6 @@ import LabelSelector from "./components/LabelSelector";
|
|||||||
import ListSelector from "./components/ListSelector";
|
import ListSelector from "./components/ListSelector";
|
||||||
import MemberSelector from "./components/MemberSelector";
|
import MemberSelector from "./components/MemberSelector";
|
||||||
import { NewChecklistForm } from "./components/NewChecklistForm";
|
import { NewChecklistForm } from "./components/NewChecklistForm";
|
||||||
import NewChecklistItemForm from "./components/NewChecklistItemForm";
|
|
||||||
import NewCommentForm from "./components/NewCommentForm";
|
import NewCommentForm from "./components/NewCommentForm";
|
||||||
|
|
||||||
interface FormValues {
|
interface FormValues {
|
||||||
@@ -213,94 +212,96 @@ export default function CardPage() {
|
|||||||
<PageHead
|
<PageHead
|
||||||
title={t`${card?.title ?? "Card"} | ${board?.name ?? "Board"}`}
|
title={t`${card?.title ?? "Card"} | ${board?.name ?? "Board"}`}
|
||||||
/>
|
/>
|
||||||
<div className="flex h-full flex-1 flex-row">
|
<div className="flex h-full flex-1 flex-row overflow-hidden">
|
||||||
<div className="m-auto flex h-full w-full max-w-[800px] flex-col overflow-hidden">
|
<div className="scrollbar-thumb-rounded-[4px] scrollbar-track-rounded-[4px] w-full flex-1 overflow-y-auto scrollbar scrollbar-track-light-200 scrollbar-thumb-light-400 hover:scrollbar-thumb-light-400 dark:scrollbar-track-dark-100 dark:scrollbar-thumb-dark-300 dark:hover:scrollbar-thumb-dark-300">
|
||||||
<div className="h-full max-h-[calc(100dvh-3rem)] overflow-y-auto p-6 md:max-h-[calc(100dvh-4rem)] md:p-8">
|
<div className="p-auto mx-auto flex h-full w-full max-w-[800px] flex-col">
|
||||||
<div className="mb-8 flex w-full items-center justify-between md:mt-6">
|
<div className="p-6 md:p-8">
|
||||||
{!card && isLoading && (
|
<div className="mb-8 flex w-full items-center justify-between md:mt-6">
|
||||||
<div className="flex space-x-2">
|
{!card && isLoading && (
|
||||||
<div className="h-[2.3rem] w-[150px] animate-pulse rounded-[5px] bg-light-300 dark:bg-dark-300" />
|
<div className="flex space-x-2">
|
||||||
<div className="h-[2.3rem] w-[300px] animate-pulse rounded-[5px] bg-light-300 dark:bg-dark-300" />
|
<div className="h-[2.3rem] w-[150px] animate-pulse rounded-[5px] bg-light-300 dark:bg-dark-300" />
|
||||||
</div>
|
<div className="h-[2.3rem] w-[300px] animate-pulse rounded-[5px] bg-light-300 dark:bg-dark-300" />
|
||||||
)}
|
</div>
|
||||||
|
)}
|
||||||
|
{card && (
|
||||||
|
<>
|
||||||
|
<Link
|
||||||
|
className="whitespace-nowrap font-bold leading-[2.3rem] tracking-tight text-light-900 dark:text-dark-900 sm:text-[1.2rem]"
|
||||||
|
href={`/boards/${board?.publicId}`}
|
||||||
|
>
|
||||||
|
{board?.name}
|
||||||
|
</Link>
|
||||||
|
<IoChevronForwardSharp
|
||||||
|
size={18}
|
||||||
|
className="mx-2 text-light-900 dark:text-dark-900"
|
||||||
|
/>
|
||||||
|
<form
|
||||||
|
onSubmit={handleSubmit(onSubmit)}
|
||||||
|
className="w-full space-y-6"
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
id="title"
|
||||||
|
{...register("title")}
|
||||||
|
onBlur={handleSubmit(onSubmit)}
|
||||||
|
className="block w-full border-0 bg-transparent p-0 py-0 font-bold tracking-tight text-neutral-900 focus:ring-0 dark:text-dark-1000 sm:text-[1.2rem]"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
<div className="flex">
|
||||||
|
<Dropdown />
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
{!card && !isLoading && (
|
||||||
|
<p className="block p-0 py-0 font-bold leading-[2.3rem] tracking-tight text-neutral-900 dark:text-dark-1000 sm:text-[1.2rem]">
|
||||||
|
{t`Card not found`}
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
{card && (
|
{card && (
|
||||||
<>
|
<>
|
||||||
<Link
|
<div className="mb-10 flex w-full max-w-2xl flex-col justify-between">
|
||||||
className="whitespace-nowrap font-bold leading-[2.3rem] tracking-tight text-light-900 dark:text-dark-900 sm:text-[1.2rem]"
|
<form
|
||||||
href={`/boards/${board?.publicId}`}
|
onSubmit={handleSubmit(onSubmit)}
|
||||||
>
|
className="w-full space-y-6"
|
||||||
{board?.name}
|
>
|
||||||
</Link>
|
<div className="mt-2">
|
||||||
<IoChevronForwardSharp
|
<Editor
|
||||||
size={18}
|
content={card.description}
|
||||||
className="mx-2 text-light-900 dark:text-dark-900"
|
onChange={(e) => setValue("description", e)}
|
||||||
|
onBlur={() => handleSubmit(onSubmit)()}
|
||||||
|
workspaceMembers={board?.workspace.members ?? []}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<Checklists
|
||||||
|
checklists={card.checklists}
|
||||||
|
cardPublicId={cardId}
|
||||||
|
activeChecklistForm={activeChecklistForm}
|
||||||
|
setActiveChecklistForm={setActiveChecklistForm}
|
||||||
/>
|
/>
|
||||||
<form
|
<div className="border-t-[1px] border-light-300 pt-12 dark:border-dark-300">
|
||||||
onSubmit={handleSubmit(onSubmit)}
|
<h2 className="text-md pb-4 font-medium text-light-1000 dark:text-dark-1000">
|
||||||
className="w-full space-y-6"
|
{t`Activity`}
|
||||||
>
|
</h2>
|
||||||
<div>
|
<div>
|
||||||
<input
|
<ActivityList
|
||||||
type="text"
|
cardPublicId={cardId}
|
||||||
id="title"
|
activities={activities ?? []}
|
||||||
{...register("title")}
|
isLoading={!card}
|
||||||
onBlur={handleSubmit(onSubmit)}
|
isAdmin={workspace.role === "admin"}
|
||||||
className="block w-full border-0 bg-transparent p-0 py-0 font-bold tracking-tight text-neutral-900 focus:ring-0 dark:text-dark-1000 sm:text-[1.2rem]"
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
<div className="mt-6">
|
||||||
<div className="flex">
|
<NewCommentForm cardPublicId={cardId} />
|
||||||
<Dropdown />
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
{!card && !isLoading && (
|
|
||||||
<p className="block p-0 py-0 font-bold leading-[2.3rem] tracking-tight text-neutral-900 dark:text-dark-1000 sm:text-[1.2rem]">
|
|
||||||
{t`Card not found`}
|
|
||||||
</p>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
{card && (
|
|
||||||
<>
|
|
||||||
<div className="mb-10 flex w-full max-w-2xl flex-col justify-between">
|
|
||||||
<form
|
|
||||||
onSubmit={handleSubmit(onSubmit)}
|
|
||||||
className="w-full space-y-6"
|
|
||||||
>
|
|
||||||
<div className="mt-2">
|
|
||||||
<Editor
|
|
||||||
content={card.description}
|
|
||||||
onChange={(e) => setValue("description", e)}
|
|
||||||
onBlur={() => handleSubmit(onSubmit)()}
|
|
||||||
workspaceMembers={board?.workspace?.members ?? []}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
<Checklists
|
|
||||||
checklists={card.checklists}
|
|
||||||
cardPublicId={cardId}
|
|
||||||
activeChecklistForm={activeChecklistForm}
|
|
||||||
setActiveChecklistForm={setActiveChecklistForm}
|
|
||||||
/>
|
|
||||||
<div className="border-t-[1px] border-light-300 pt-12 dark:border-dark-300">
|
|
||||||
<h2 className="text-md pb-4 font-medium text-light-1000 dark:text-dark-1000">
|
|
||||||
{t`Activity`}
|
|
||||||
</h2>
|
|
||||||
<div>
|
|
||||||
<ActivityList
|
|
||||||
cardPublicId={cardId}
|
|
||||||
activities={activities ?? []}
|
|
||||||
isLoading={!card}
|
|
||||||
isAdmin={workspace.role === "admin"}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div className="mt-6">
|
|
||||||
<NewCommentForm cardPublicId={cardId} />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import Link from "next/link";
|
|||||||
import { useRouter } from "next/router";
|
import { useRouter } from "next/router";
|
||||||
import { t } from "@lingui/core/macro";
|
import { t } from "@lingui/core/macro";
|
||||||
import { keepPreviousData } from "@tanstack/react-query";
|
import { keepPreviousData } from "@tanstack/react-query";
|
||||||
|
import { env } from "next-runtime-env";
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { HiLink, HiOutlineLockClosed } from "react-icons/hi2";
|
import { HiLink, HiOutlineLockClosed } from "react-icons/hi2";
|
||||||
|
|
||||||
@@ -19,6 +20,10 @@ import Card from "~/views/board/components/Card";
|
|||||||
import Filters from "~/views/board/components/Filters";
|
import Filters from "~/views/board/components/Filters";
|
||||||
import { CardModal } from "./CardModal";
|
import { CardModal } from "./CardModal";
|
||||||
|
|
||||||
|
const IS_CLOUD = env("NEXT_PUBLIC_KAN_ENV") === "cloud";
|
||||||
|
const HIDE_POWERED_BY =
|
||||||
|
env("NEXT_PUBLIC_WHITE_LABEL_HIDE_POWERED_BY") === "true";
|
||||||
|
|
||||||
export default function PublicBoardView() {
|
export default function PublicBoardView() {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { showPopup } = usePopup();
|
const { showPopup } = usePopup();
|
||||||
@@ -194,12 +199,26 @@ export default function PublicBoardView() {
|
|||||||
<CopyBoardLink />
|
<CopyBoardLink />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Link
|
{IS_CLOUD && (
|
||||||
className="text-lg font-bold tracking-tight text-neutral-900 dark:text-dark-1000"
|
<Link
|
||||||
href="/"
|
className="text-lg font-bold tracking-tight text-neutral-900 dark:text-dark-1000"
|
||||||
>
|
href="/"
|
||||||
kan.bn
|
>
|
||||||
</Link>
|
kan.bn
|
||||||
|
</Link>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{!IS_CLOUD && !HIDE_POWERED_BY && (
|
||||||
|
<a
|
||||||
|
href="https://kan.bn"
|
||||||
|
target="_blank"
|
||||||
|
rel="noreferrer noopener"
|
||||||
|
className="absolute right-[1rem] inline-flex items-center gap-[0.175rem] rounded-full border border-light-300 bg-light-50 px-3 py-1 text-[11px] font-medium text-light-950 shadow-sm transition-colors hover:bg-light-100 dark:border-dark-300 dark:bg-dark-50 dark:text-dark-900 dark:hover:bg-dark-100"
|
||||||
|
>
|
||||||
|
<span>{`Powered by`}</span>
|
||||||
|
<span className="font-semibold">kan.bn</span>
|
||||||
|
</a>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<Popup />
|
<Popup />
|
||||||
|
|||||||
@@ -35,6 +35,9 @@ services:
|
|||||||
- NEXT_PUBLIC_AVATAR_BUCKET_NAME=${NEXT_PUBLIC_AVATAR_BUCKET_NAME}
|
- NEXT_PUBLIC_AVATAR_BUCKET_NAME=${NEXT_PUBLIC_AVATAR_BUCKET_NAME}
|
||||||
- NEXT_PUBLIC_STORAGE_DOMAIN=${NEXT_PUBLIC_STORAGE_DOMAIN}
|
- NEXT_PUBLIC_STORAGE_DOMAIN=${NEXT_PUBLIC_STORAGE_DOMAIN}
|
||||||
|
|
||||||
|
# White label
|
||||||
|
- NEXT_PUBLIC_WHITE_LABEL_HIDE_POWERED_BY=${NEXT_PUBLIC_WHITE_LABEL_HIDE_POWERED_BY}
|
||||||
|
|
||||||
# Auth config (optional)
|
# Auth config (optional)
|
||||||
- NEXT_PUBLIC_ALLOW_CREDENTIALS=${NEXT_PUBLIC_ALLOW_CREDENTIALS}
|
- NEXT_PUBLIC_ALLOW_CREDENTIALS=${NEXT_PUBLIC_ALLOW_CREDENTIALS}
|
||||||
- NEXT_PUBLIC_DISABLE_SIGN_UP=${NEXT_PUBLIC_DISABLE_SIGN_UP}
|
- NEXT_PUBLIC_DISABLE_SIGN_UP=${NEXT_PUBLIC_DISABLE_SIGN_UP}
|
||||||
|
|||||||
@@ -93,6 +93,7 @@
|
|||||||
"SMTP_PASSWORD",
|
"SMTP_PASSWORD",
|
||||||
"SMTP_SECURE",
|
"SMTP_SECURE",
|
||||||
"NEXT_PUBLIC_KAN_ENV",
|
"NEXT_PUBLIC_KAN_ENV",
|
||||||
|
"NEXT_PUBLIC_WHITE_LABEL_HIDE_POWERED_BY",
|
||||||
"STRIPE_SECRET_KEY",
|
"STRIPE_SECRET_KEY",
|
||||||
"STRIPE_WEBHOOK_SECRET",
|
"STRIPE_WEBHOOK_SECRET",
|
||||||
"STRIPE_PRO_PLAN_PRICE_ID",
|
"STRIPE_PRO_PLAN_PRICE_ID",
|
||||||
|
|||||||
Reference in New Issue
Block a user