Compare commits
8 Commits
fix/kan-16
...
feat/seats
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9df9b9146c | ||
|
|
7966ec01f5 | ||
|
|
2779c06bcc | ||
|
|
4f9841ceaf | ||
|
|
a596b1c40b | ||
|
|
bc98fc848f | ||
|
|
5f4678ab4e | ||
|
|
a7c68db90e |
@@ -70,7 +70,7 @@ export default async function handler(
|
|||||||
mode: "subscription",
|
mode: "subscription",
|
||||||
line_items: [
|
line_items: [
|
||||||
{
|
{
|
||||||
price: process.env.STRIPE_PRO_PLAN_MONTHLY_PRICE_ID,
|
price: process.env.STRIPE_PRO_PLAN_PRICE_ID,
|
||||||
quantity: 1,
|
quantity: 1,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ export default async function handler(
|
|||||||
const event = stripe.webhooks.constructEvent(
|
const event = stripe.webhooks.constructEvent(
|
||||||
rawBody,
|
rawBody,
|
||||||
sig,
|
sig,
|
||||||
process.env.STRIPE_WEBHOOK_SECRET_LEGACY!,
|
process.env.STRIPE_WEBHOOK_SECRET!,
|
||||||
);
|
);
|
||||||
|
|
||||||
const { db } = await createNextApiContext(req);
|
const { db } = await createNextApiContext(req);
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import { t } from "@lingui/core/macro";
|
import { t } from "@lingui/core/macro";
|
||||||
import { env } from "next-runtime-env";
|
|
||||||
import { HiEllipsisHorizontal, HiOutlinePlusSmall } from "react-icons/hi2";
|
import { HiEllipsisHorizontal, HiOutlinePlusSmall } from "react-icons/hi2";
|
||||||
import { twMerge } from "tailwind-merge";
|
import { twMerge } from "tailwind-merge";
|
||||||
|
|
||||||
@@ -12,6 +11,7 @@ import FeedbackModal from "~/components/FeedbackModal";
|
|||||||
import Modal from "~/components/modal";
|
import Modal from "~/components/modal";
|
||||||
import { NewWorkspaceForm } from "~/components/NewWorkspaceForm";
|
import { NewWorkspaceForm } from "~/components/NewWorkspaceForm";
|
||||||
import { PageHead } from "~/components/PageHead";
|
import { PageHead } from "~/components/PageHead";
|
||||||
|
import { env } from "~/env";
|
||||||
import { useModal } from "~/providers/modal";
|
import { useModal } from "~/providers/modal";
|
||||||
import { useWorkspace } from "~/providers/workspace";
|
import { useWorkspace } from "~/providers/workspace";
|
||||||
import { api } from "~/utils/api";
|
import { api } from "~/utils/api";
|
||||||
@@ -171,7 +171,7 @@ export default function MembersPage() {
|
|||||||
{t`Members`}
|
{t`Members`}
|
||||||
</h1>
|
</h1>
|
||||||
<div className="flex items-center gap-3">
|
<div className="flex items-center gap-3">
|
||||||
{env("NEXT_PUBLIC_KAN_ENV") === "cloud" && (
|
{env.NEXT_PUBLIC_KAN_ENV === "cloud" && (
|
||||||
<div
|
<div
|
||||||
className={twMerge(
|
className={twMerge(
|
||||||
"flex items-center rounded-full border px-3 py-1 text-center text-xs",
|
"flex items-center rounded-full border px-3 py-1 text-center text-xs",
|
||||||
|
|||||||
@@ -22,11 +22,6 @@ services:
|
|||||||
# Stripe
|
# Stripe
|
||||||
- STRIPE_SECRET_KEY=${STRIPE_SECRET_KEY}
|
- STRIPE_SECRET_KEY=${STRIPE_SECRET_KEY}
|
||||||
- STRIPE_WEBHOOK_SECRET=${STRIPE_WEBHOOK_SECRET}
|
- STRIPE_WEBHOOK_SECRET=${STRIPE_WEBHOOK_SECRET}
|
||||||
- STRIPE_WEBHOOK_SECRET_LEGACY=${STRIPE_WEBHOOK_SECRET_LEGACY}
|
|
||||||
- STRIPE_TEAM_PLAN_MONTHLY_PRICE_ID=${STRIPE_TEAM_PLAN_MONTHLY_PRICE_ID}
|
|
||||||
- STRIPE_TEAM_PLAN_YEARLY_PRICE_ID=${STRIPE_TEAM_PLAN_YEARLY_PRICE_ID}
|
|
||||||
- STRIPE_PRO_PLAN_MONTHLY_PRICE_ID=${STRIPE_PRO_PLAN_MONTHLY_PRICE_ID}
|
|
||||||
- STRIPE_PRO_PLAN_YEARLY_PRICE_ID=${STRIPE_PRO_PLAN_YEARLY_PRICE_ID}
|
|
||||||
|
|
||||||
# Email
|
# Email
|
||||||
- SMTP_HOST=${SMTP_HOST}
|
- SMTP_HOST=${SMTP_HOST}
|
||||||
|
|||||||
@@ -114,13 +114,13 @@ async function downloadImage(url: string): Promise<Buffer> {
|
|||||||
export const initAuth = (db: dbClient) => {
|
export const initAuth = (db: dbClient) => {
|
||||||
return betterAuth({
|
return betterAuth({
|
||||||
secret: process.env.BETTER_AUTH_SECRET!,
|
secret: process.env.BETTER_AUTH_SECRET!,
|
||||||
baseURL: env("NEXT_PUBLIC_BASE_URL"),
|
baseURL: process.env.NEXT_PUBLIC_BASE_URL!,
|
||||||
trustedOrigins: process.env.BETTER_AUTH_TRUSTED_ORIGINS
|
trustedOrigins: process.env.BETTER_AUTH_TRUSTED_ORIGINS
|
||||||
? [
|
? [
|
||||||
env("NEXT_PUBLIC_BASE_URL") ?? "",
|
process.env.NEXT_PUBLIC_BASE_URL!,
|
||||||
...process.env.BETTER_AUTH_TRUSTED_ORIGINS.split(","),
|
...process.env.BETTER_AUTH_TRUSTED_ORIGINS.split(","),
|
||||||
]
|
]
|
||||||
: [env("NEXT_PUBLIC_BASE_URL") ?? ""],
|
: [process.env.NEXT_PUBLIC_BASE_URL!],
|
||||||
database: drizzleAdapter(db, {
|
database: drizzleAdapter(db, {
|
||||||
provider: "pg",
|
provider: "pg",
|
||||||
schema: {
|
schema: {
|
||||||
@@ -196,13 +196,6 @@ export const initAuth = (db: dbClient) => {
|
|||||||
|
|
||||||
return isUserInWorkspace;
|
return isUserInWorkspace;
|
||||||
},
|
},
|
||||||
getCheckoutSessionParams: () => {
|
|
||||||
return {
|
|
||||||
params: {
|
|
||||||
allow_promotion_codes: true,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
]
|
]
|
||||||
@@ -324,17 +317,37 @@ export const initAuth = (db: dbClient) => {
|
|||||||
},
|
},
|
||||||
hooks: {
|
hooks: {
|
||||||
after: createAuthMiddleware(async (ctx) => {
|
after: createAuthMiddleware(async (ctx) => {
|
||||||
if (
|
if (ctx.path.startsWith("/get-session")) {
|
||||||
|
const user = ctx.context.session?.user;
|
||||||
|
|
||||||
|
if (
|
||||||
|
env("NEXT_PUBLIC_KAN_ENV") === "cloud" &&
|
||||||
|
user &&
|
||||||
|
!user.stripeCustomerId
|
||||||
|
) {
|
||||||
|
const stripe = createStripeClient();
|
||||||
|
const stripeCustomer = await stripe.customers.create({
|
||||||
|
email: user.email,
|
||||||
|
metadata: {
|
||||||
|
userId: user.id,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
await userRepo.update(db, user.id, {
|
||||||
|
stripeCustomerId: stripeCustomer.id,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else if (
|
||||||
ctx.path === "/magic-link/verify" &&
|
ctx.path === "/magic-link/verify" &&
|
||||||
(ctx.query?.callbackURL as string | undefined)?.includes(
|
(ctx.query?.callbackURL as string | undefined)?.includes(
|
||||||
"type=invite",
|
"type=invite",
|
||||||
)
|
) &&
|
||||||
|
ctx.query?.memberPublicId
|
||||||
) {
|
) {
|
||||||
const userId = ctx.context.newSession?.session.userId;
|
const userId = ctx.context.newSession?.session.userId;
|
||||||
const callbackURL = ctx.query?.callbackURL as string | undefined;
|
const memberPublicId = ctx.query.memberPublicId as string;
|
||||||
const memberPublicId = callbackURL?.split("memberPublicId=")[1];
|
|
||||||
|
|
||||||
if (userId && memberPublicId) {
|
if (userId) {
|
||||||
const member = await memberRepo.getByPublicId(db, memberPublicId);
|
const member = await memberRepo.getByPublicId(db, memberPublicId);
|
||||||
|
|
||||||
if (member?.id) {
|
if (member?.id) {
|
||||||
|
|||||||
@@ -45,14 +45,14 @@ export const sendEmail = async (
|
|||||||
html,
|
html,
|
||||||
};
|
};
|
||||||
|
|
||||||
// if (cloudMailerClient) {
|
if (cloudMailerClient) {
|
||||||
// const response = await cloudMailerClient.emails.send({
|
const response = await cloudMailerClient.emails.send({
|
||||||
// ...options,
|
...options,
|
||||||
// body: html,
|
body: html,
|
||||||
// });
|
});
|
||||||
|
|
||||||
// return response;
|
return response;
|
||||||
// }
|
}
|
||||||
|
|
||||||
const response = await transporter.sendMail(options);
|
const response = await transporter.sendMail(options);
|
||||||
|
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ export const updateSubscriptionSeats = async (
|
|||||||
quantity: newQuantity,
|
quantity: newQuantity,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
proration_behavior: "create_prorations",
|
proration_behavior: "always_invoice", // Invoice immediately
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -99,11 +99,7 @@
|
|||||||
"NEXT_PUBLIC_WHITE_LABEL_HIDE_POWERED_BY",
|
"NEXT_PUBLIC_WHITE_LABEL_HIDE_POWERED_BY",
|
||||||
"STRIPE_SECRET_KEY",
|
"STRIPE_SECRET_KEY",
|
||||||
"STRIPE_WEBHOOK_SECRET",
|
"STRIPE_WEBHOOK_SECRET",
|
||||||
"STRIPE_WEBHOOK_SECRET_LEGACY",
|
"STRIPE_PRO_PLAN_PRICE_ID",
|
||||||
"STRIPE_PRO_PLAN_MONTHLY_PRICE_ID",
|
|
||||||
"STRIPE_PRO_PLAN_YEARLY_PRICE_ID",
|
|
||||||
"STRIPE_TEAM_PLAN_MONTHLY_PRICE_ID",
|
|
||||||
"STRIPE_TEAM_PLAN_YEARLY_PRICE_ID",
|
|
||||||
"NEXT_PUBLIC_STORAGE_DOMAIN",
|
"NEXT_PUBLIC_STORAGE_DOMAIN",
|
||||||
"NEXT_PUBLIC_STORAGE_URL",
|
"NEXT_PUBLIC_STORAGE_URL",
|
||||||
"NEXT_PUBLIC_AVATAR_BUCKET_NAME",
|
"NEXT_PUBLIC_AVATAR_BUCKET_NAME",
|
||||||
|
|||||||
Reference in New Issue
Block a user