2025-05-18 20:46:59 +02:00
|
|
|
import {betterAuth} from "better-auth";
|
|
|
|
|
import {drizzleAdapter} from "better-auth/adapters/drizzle";
|
2025-07-26 14:43:59 +02:00
|
|
|
import * as drizzleDb from "@/db";
|
2025-05-18 20:46:59 +02:00
|
|
|
import {db} from "@/db";
|
|
|
|
|
import {env} from "@/env.mjs";
|
|
|
|
|
import {nextCookies} from "better-auth/next-js";
|
2025-12-21 16:55:12 +01:00
|
|
|
import {admin as adminPlugin, openAPI, Organization, organization, twoFactor} from "better-auth/plugins";
|
2025-05-18 20:46:59 +02:00
|
|
|
import {ac, admin, orgAdmin, orgMember, orgOwner, pending, superadmin, user} from "@/lib/auth/permissions";
|
|
|
|
|
import {headers} from "next/headers";
|
|
|
|
|
import {count, eq} from "drizzle-orm";
|
2025-11-01 14:50:08 +01:00
|
|
|
import {MemberWithUser, OrganizationWithMembersAndUsers} from "@/db/schema/03_organization";
|
2025-11-22 17:20:52 +01:00
|
|
|
import {sendEmail} from "@/lib/email/email-helper";
|
|
|
|
|
import {render} from "@react-email/render";
|
2025-12-21 16:55:12 +01:00
|
|
|
import {SUPPORTED_PROVIDERS} from "../../../portabase.config";
|
|
|
|
|
import {withUpdatedAt} from "@/db/utils";
|
2025-12-23 18:25:31 +01:00
|
|
|
import EmailVerification from "@/components/emails/auth/email-verification";
|
|
|
|
|
import EmailForgotPassword from "@/components/emails/auth/email-forgot-password";
|
|
|
|
|
import {getDeviceDetails} from "@/utils/detection";
|
|
|
|
|
import EmailNewLogin from "@/components/emails/auth/email-new-login";
|
2025-05-16 15:54:17 +02:00
|
|
|
|
|
|
|
|
export const auth = betterAuth({
|
|
|
|
|
database: drizzleAdapter(db, {
|
|
|
|
|
provider: "pg",
|
2025-07-16 12:36:11 +02:00
|
|
|
schema: drizzleDb.schemas,
|
2025-05-16 15:54:17 +02:00
|
|
|
}),
|
2025-12-22 20:32:18 +01:00
|
|
|
appName: env.PROJECT_NAME!,
|
2025-12-21 19:27:00 +01:00
|
|
|
baseURL: env.PROJECT_URL,
|
2025-07-17 12:43:00 +02:00
|
|
|
secret: env.PROJECT_SECRET,
|
2025-05-16 15:54:17 +02:00
|
|
|
emailAndPassword: {
|
|
|
|
|
enabled: true,
|
|
|
|
|
requireEmailVerification: false,
|
2025-12-23 18:25:31 +01:00
|
|
|
sendResetPassword: async ({user, token}, request) => {
|
2025-12-21 16:55:12 +01:00
|
|
|
|
|
|
|
|
const [updatedUser] = await db.update(drizzleDb.schemas.user).set(withUpdatedAt({
|
|
|
|
|
emailVerified: true,
|
|
|
|
|
})).where(eq(drizzleDb.schemas.user.id, user.id)).returning();
|
|
|
|
|
|
2025-11-22 17:20:52 +01:00
|
|
|
await sendEmail({
|
|
|
|
|
to: user.email,
|
|
|
|
|
subject: "Reset your password",
|
2025-12-23 18:25:31 +01:00
|
|
|
html: await render(
|
|
|
|
|
EmailForgotPassword({
|
|
|
|
|
firstname: user.name!,
|
|
|
|
|
token,
|
|
|
|
|
}),
|
|
|
|
|
{}
|
|
|
|
|
),
|
2025-11-22 17:20:52 +01:00
|
|
|
});
|
2025-12-21 16:55:12 +01:00
|
|
|
|
2025-05-16 15:54:17 +02:00
|
|
|
},
|
2025-11-22 17:20:52 +01:00
|
|
|
onPasswordReset: async ({user}, request) => {
|
|
|
|
|
console.log(`Password for user ${user.email} has been reset.`);
|
|
|
|
|
},
|
2025-05-16 15:54:17 +02:00
|
|
|
},
|
2025-12-21 16:55:12 +01:00
|
|
|
emailVerification: {
|
|
|
|
|
async sendVerificationEmail({user, token, url}) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
await sendEmail({
|
|
|
|
|
to: user.email,
|
|
|
|
|
subject: "Portabase Email Verification",
|
|
|
|
|
html: await render(EmailVerification({
|
|
|
|
|
firstname: user.name,
|
|
|
|
|
url: url
|
|
|
|
|
})),
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
await (
|
|
|
|
|
await auth.$context
|
|
|
|
|
).internalAdapter.updateUser(user.id, {
|
|
|
|
|
emailVerified: false,
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
async afterEmailVerification(user) {
|
|
|
|
|
await (
|
|
|
|
|
await auth.$context
|
|
|
|
|
).internalAdapter.updateUser(user.id, {
|
|
|
|
|
emailVerified: true,
|
|
|
|
|
});
|
2025-05-16 15:54:17 +02:00
|
|
|
},
|
|
|
|
|
},
|
2025-12-21 16:55:12 +01:00
|
|
|
socialProviders: SUPPORTED_PROVIDERS.reduce((acc: any, provider: any) => {
|
|
|
|
|
if (provider.id === "credential") return acc;
|
|
|
|
|
if (provider.id === "google") {
|
|
|
|
|
acc.google = {
|
|
|
|
|
clientId: env.AUTH_GOOGLE_ID! as string,
|
|
|
|
|
clientSecret: env.AUTH_GOOGLE_SECRET! as string,
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
return acc;
|
|
|
|
|
}, {}),
|
|
|
|
|
account: {
|
|
|
|
|
accountLinking: {
|
|
|
|
|
enabled: true,
|
2025-12-23 21:44:52 +01:00
|
|
|
trustedProviders: ["google", "github", "credential"],
|
|
|
|
|
allowDifferentEmails: false
|
2025-12-21 16:55:12 +01:00
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
|
2025-05-16 15:54:17 +02:00
|
|
|
plugins: [
|
|
|
|
|
openAPI(),
|
|
|
|
|
nextCookies(),
|
2025-12-21 16:55:12 +01:00
|
|
|
twoFactor(),
|
2025-05-16 15:54:17 +02:00
|
|
|
organization({
|
|
|
|
|
ac,
|
|
|
|
|
roles: {
|
2025-07-26 14:43:59 +02:00
|
|
|
owner: orgOwner,
|
|
|
|
|
admin: orgAdmin,
|
|
|
|
|
member: orgMember,
|
2025-05-16 15:54:17 +02:00
|
|
|
},
|
|
|
|
|
}),
|
|
|
|
|
adminPlugin({
|
|
|
|
|
adminRoles: ["admin", "superadmin"],
|
2025-07-16 12:36:11 +02:00
|
|
|
defaultRole: "pending",
|
2025-05-16 15:54:17 +02:00
|
|
|
ac,
|
|
|
|
|
roles: {
|
|
|
|
|
admin,
|
|
|
|
|
user,
|
|
|
|
|
pending,
|
|
|
|
|
superadmin,
|
|
|
|
|
},
|
|
|
|
|
}),
|
|
|
|
|
],
|
|
|
|
|
advanced: {
|
|
|
|
|
database: {
|
|
|
|
|
generateId: false,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
user: {
|
2025-07-28 16:53:21 +02:00
|
|
|
deleteUser: {
|
|
|
|
|
enabled: true,
|
2025-12-21 16:55:12 +01:00
|
|
|
},
|
|
|
|
|
changeEmail: {
|
|
|
|
|
enabled: true,
|
2025-07-28 16:53:21 +02:00
|
|
|
},
|
2025-05-16 15:54:17 +02:00
|
|
|
additionalFields: {
|
|
|
|
|
deletedAt: {
|
2025-12-09 21:23:15 +01:00
|
|
|
type: "number",
|
2025-05-16 15:54:17 +02:00
|
|
|
nullable: true,
|
|
|
|
|
required: false,
|
|
|
|
|
},
|
2025-12-22 20:32:18 +01:00
|
|
|
theme: {
|
|
|
|
|
type: "string",
|
|
|
|
|
},
|
|
|
|
|
lastConnectedAt: {
|
|
|
|
|
type: "date",
|
|
|
|
|
},
|
|
|
|
|
lastChangedPasswordAt: {
|
|
|
|
|
type: "date",
|
|
|
|
|
},
|
2025-05-16 15:54:17 +02:00
|
|
|
},
|
|
|
|
|
},
|
2025-07-16 12:36:11 +02:00
|
|
|
databaseHooks: {
|
|
|
|
|
user: {
|
|
|
|
|
create: {
|
|
|
|
|
async before(user, context) {
|
|
|
|
|
const userCount = (await db.select({count: count()}).from(drizzleDb.schemas.user))[0].count;
|
|
|
|
|
const role = userCount === 0 ? "superadmin" : "pending";
|
2025-12-23 21:44:52 +01:00
|
|
|
// const role = "admin";
|
2025-07-16 12:36:11 +02:00
|
|
|
return {
|
|
|
|
|
data: {
|
|
|
|
|
...user,
|
|
|
|
|
role,
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
},
|
|
|
|
|
async after(user, context) {
|
2025-07-28 16:53:21 +02:00
|
|
|
const userCount = (await db.select({count: count()}).from(drizzleDb.schemas.user))[0].count;
|
|
|
|
|
const role = userCount === 0 ? "owner" : "admin";
|
|
|
|
|
|
2025-07-16 12:36:11 +02:00
|
|
|
|
2025-07-27 21:26:31 +02:00
|
|
|
const defaultOrgSlug = "default"; // change this if your default org has a different slug
|
|
|
|
|
const defaultOrg = await db.query.organization.findFirst({
|
|
|
|
|
where: eq(drizzleDb.schemas.organization.slug, defaultOrgSlug),
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (defaultOrg) {
|
2025-07-28 16:53:21 +02:00
|
|
|
console.log(user)
|
2025-07-27 21:26:31 +02:00
|
|
|
await db.insert(drizzleDb.schemas.member).values({
|
|
|
|
|
userId: user.id,
|
|
|
|
|
organizationId: defaultOrg.id,
|
2025-07-28 16:53:21 +02:00
|
|
|
role: role,
|
2025-07-16 12:36:11 +02:00
|
|
|
});
|
2025-07-27 21:26:31 +02:00
|
|
|
} else {
|
|
|
|
|
console.warn("Default organization not found. Cannot assign member.");
|
2025-07-16 12:36:11 +02:00
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
session: {
|
|
|
|
|
create: {
|
|
|
|
|
before: async (session, context) => {
|
|
|
|
|
const userId = session.userId;
|
|
|
|
|
|
2025-07-26 16:34:06 +02:00
|
|
|
let memberships = await db.query.member.findMany({
|
2025-07-16 12:36:11 +02:00
|
|
|
where: eq(drizzleDb.schemas.member.userId, userId),
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
data: {
|
2025-07-26 16:34:06 +02:00
|
|
|
activeOrganizationId: memberships[0].organizationId,
|
2025-07-16 12:36:11 +02:00
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
},
|
2025-12-23 21:44:52 +01:00
|
|
|
// after: async (session) => {
|
|
|
|
|
// const user = await db.query.user.findFirst({
|
|
|
|
|
// where: eq(drizzleDb.schemas.user.id, session.userId),
|
|
|
|
|
// });
|
|
|
|
|
//
|
|
|
|
|
// if (user && user.role != "pending") {
|
|
|
|
|
// const deviceInfo = getDeviceDetails(session.userAgent);
|
|
|
|
|
// await sendEmail({
|
|
|
|
|
// to: user.email,
|
|
|
|
|
// subject: "New login to your account",
|
|
|
|
|
// html: await render(
|
|
|
|
|
// EmailNewLogin({
|
|
|
|
|
// firstname: user.name!,
|
|
|
|
|
// os: deviceInfo.os,
|
|
|
|
|
// browser: deviceInfo.browser,
|
|
|
|
|
// ipAddress: session.ipAddress!,
|
|
|
|
|
// }),
|
|
|
|
|
// {}
|
|
|
|
|
// ),
|
|
|
|
|
// });
|
|
|
|
|
//
|
|
|
|
|
// (await auth.$context).internalAdapter.updateUser(user.id, {
|
|
|
|
|
// lastConnectedAt: new Date(),
|
|
|
|
|
// });
|
|
|
|
|
// }
|
|
|
|
|
// },
|
2025-12-23 18:25:31 +01:00
|
|
|
after: async (session) => {
|
|
|
|
|
const user = await db.query.user.findFirst({
|
|
|
|
|
where: eq(drizzleDb.schemas.user.id, session.userId),
|
|
|
|
|
});
|
|
|
|
|
|
2025-12-23 21:44:52 +01:00
|
|
|
if (!user) return;
|
2025-12-23 18:25:31 +01:00
|
|
|
|
2025-12-23 21:44:52 +01:00
|
|
|
const createdAtDiff = new Date(session.createdAt).getTime() - new Date(user.createdAt).getTime();
|
|
|
|
|
|
|
|
|
|
if (createdAtDiff < 5000) {
|
|
|
|
|
console.log(`Skipping new login email for freshly created user ${user.email}`);
|
|
|
|
|
return;
|
2025-12-23 18:25:31 +01:00
|
|
|
}
|
2025-12-23 21:44:52 +01:00
|
|
|
|
|
|
|
|
if (user.role === "pending") return;
|
|
|
|
|
|
|
|
|
|
const deviceInfo = getDeviceDetails(session.userAgent);
|
|
|
|
|
|
|
|
|
|
await sendEmail({
|
|
|
|
|
to: user.email,
|
|
|
|
|
subject: "New login to your account",
|
|
|
|
|
html: await render(
|
|
|
|
|
EmailNewLogin({
|
|
|
|
|
firstname: user.name!,
|
|
|
|
|
os: deviceInfo.os,
|
|
|
|
|
browser: deviceInfo.browser,
|
|
|
|
|
ipAddress: session.ipAddress!,
|
|
|
|
|
}),
|
|
|
|
|
{}
|
|
|
|
|
),
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
(await auth.$context).internalAdapter.updateUser(user.id, {
|
|
|
|
|
lastConnectedAt: new Date(),
|
|
|
|
|
});
|
2025-12-23 18:25:31 +01:00
|
|
|
},
|
2025-07-16 12:36:11 +02:00
|
|
|
},
|
|
|
|
|
},
|
2025-07-26 16:34:06 +02:00
|
|
|
|
2025-07-16 12:36:11 +02:00
|
|
|
},
|
2025-05-16 15:54:17 +02:00
|
|
|
session: {
|
|
|
|
|
additionalFields: {
|
|
|
|
|
activeOrganizationId: {
|
|
|
|
|
type: "string",
|
|
|
|
|
required: false,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
/* databaseHooks: {
|
|
|
|
|
session: {
|
|
|
|
|
create: {
|
|
|
|
|
before: async (session) => {
|
|
|
|
|
const organizationId = await getLastOrganizationOrFirst(session.userId);
|
|
|
|
|
|
|
|
|
|
if (!organizationId) {
|
|
|
|
|
return {
|
|
|
|
|
...session,
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
console.log("sessionId", session.id);
|
|
|
|
|
|
|
|
|
|
const [aa] = await db
|
|
|
|
|
.update(drizzleUser.session)
|
|
|
|
|
.set({ activeOrganizationId: organizationId })
|
|
|
|
|
.where(eq(drizzleUser.session.id, session.id))
|
|
|
|
|
.returning();
|
|
|
|
|
|
|
|
|
|
console.log("aaaaa", aa);
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
...session,
|
|
|
|
|
activeOrganizationId: organizationId,
|
|
|
|
|
};
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},*/
|
2025-11-04 08:48:46 +01:00
|
|
|
trustedOrigins: [env.PROJECT_URL!, "http://app"],
|
2025-05-16 15:54:17 +02:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
/*export const signUpUser = async (email: string, password: string, name: string) => {
|
|
|
|
|
const user = await auth.api.signUpEmail({
|
|
|
|
|
body: {
|
|
|
|
|
email,
|
|
|
|
|
password,
|
|
|
|
|
name,
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
return user;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const signInUser = async (email: string, password: string) => {
|
|
|
|
|
const user = await auth.api.signInEmail({
|
|
|
|
|
body: {
|
|
|
|
|
email,
|
|
|
|
|
password,
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
return user;
|
|
|
|
|
};*/
|
|
|
|
|
|
|
|
|
|
export const createUser = async (name: string, email: string, password: string, role: "user" | "pending" | "admin" | "superadmin" = "pending") => {
|
2025-05-18 20:46:59 +02:00
|
|
|
return await auth.api.createUser({
|
2025-05-16 15:54:17 +02:00
|
|
|
headers: await headers(),
|
|
|
|
|
body: {
|
|
|
|
|
name,
|
|
|
|
|
email,
|
|
|
|
|
password,
|
|
|
|
|
role,
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const getSessions = async () => {
|
2025-05-18 20:46:59 +02:00
|
|
|
return await auth.api.listSessions({
|
2025-05-16 15:54:17 +02:00
|
|
|
headers: await headers(),
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const getSession = async () => {
|
2025-05-18 20:46:59 +02:00
|
|
|
return await auth.api.getSession({
|
2025-05-16 15:54:17 +02:00
|
|
|
headers: await headers(),
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const revokeSession = async (e: string) => {
|
|
|
|
|
try {
|
2025-07-16 12:36:11 +02:00
|
|
|
const {status} = await auth.api.revokeSession({
|
2025-05-16 15:54:17 +02:00
|
|
|
body: {
|
|
|
|
|
token: e,
|
|
|
|
|
},
|
|
|
|
|
headers: await headers(),
|
|
|
|
|
});
|
|
|
|
|
return status;
|
2025-07-16 12:36:11 +02:00
|
|
|
} catch (e) {
|
|
|
|
|
}
|
2025-05-16 15:54:17 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const getAccounts = async () => {
|
2025-05-18 20:46:59 +02:00
|
|
|
return await auth.api.listUserAccounts({
|
2025-05-16 15:54:17 +02:00
|
|
|
headers: await headers(),
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const unlinkAccount = async (provider: string, account: string) => {
|
|
|
|
|
try {
|
2025-07-16 12:36:11 +02:00
|
|
|
const {status} = await auth.api.unlinkAccount({
|
2025-05-16 15:54:17 +02:00
|
|
|
body: {
|
|
|
|
|
providerId: provider,
|
|
|
|
|
accountId: account,
|
|
|
|
|
},
|
|
|
|
|
headers: await headers(),
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
return status;
|
2025-07-16 12:36:11 +02:00
|
|
|
} catch (e) {
|
|
|
|
|
}
|
2025-05-16 15:54:17 +02:00
|
|
|
};
|
2025-11-03 11:37:14 +01:00
|
|
|
|
2025-05-18 20:46:59 +02:00
|
|
|
export const getOrganization = async ({
|
|
|
|
|
organizationId,
|
|
|
|
|
organizationSlug,
|
|
|
|
|
}: {
|
|
|
|
|
organizationId?: string;
|
|
|
|
|
organizationSlug?: string;
|
2025-07-26 14:43:59 +02:00
|
|
|
} = {}): Promise<OrganizationWithMembersAndUsers | null> => {
|
2025-07-16 12:36:11 +02:00
|
|
|
const query =
|
|
|
|
|
organizationId != null
|
2025-09-23 20:35:48 +02:00
|
|
|
? {organizationId}
|
2025-07-16 12:36:11 +02:00
|
|
|
: organizationSlug != null
|
2025-09-23 20:35:48 +02:00
|
|
|
? {organizationSlug}
|
2025-07-16 12:36:11 +02:00
|
|
|
: undefined;
|
2025-05-16 15:54:17 +02:00
|
|
|
|
2025-05-18 20:46:59 +02:00
|
|
|
try {
|
2025-07-26 14:43:59 +02:00
|
|
|
const response = await auth.api.getFullOrganization({
|
2025-05-18 20:46:59 +02:00
|
|
|
headers: await headers(),
|
2025-09-23 20:35:48 +02:00
|
|
|
...(query ? {query} : {}),
|
2025-05-18 20:46:59 +02:00
|
|
|
});
|
2025-07-26 14:43:59 +02:00
|
|
|
|
|
|
|
|
return response as OrganizationWithMembersAndUsers;
|
2025-05-18 20:46:59 +02:00
|
|
|
} catch (e) {
|
|
|
|
|
console.error(e);
|
|
|
|
|
return null;
|
|
|
|
|
}
|
2025-05-16 15:54:17 +02:00
|
|
|
};
|
|
|
|
|
|
2025-07-29 08:51:50 +02:00
|
|
|
export const listOrganizations = async (): Promise<Organization[] | null> => {
|
2025-05-16 15:54:17 +02:00
|
|
|
try {
|
2025-05-18 20:46:59 +02:00
|
|
|
return await auth.api.listOrganizations({
|
2025-05-16 15:54:17 +02:00
|
|
|
headers: await headers(),
|
2025-07-29 08:51:50 +02:00
|
|
|
}) as Organization[];
|
2025-07-16 12:36:11 +02:00
|
|
|
} catch (e) {
|
2025-07-29 08:51:50 +02:00
|
|
|
return null;
|
2025-07-16 12:36:11 +02:00
|
|
|
}
|
2025-05-16 15:54:17 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const getLastOrganizationOrFirst = async (userId: string) => {
|
|
|
|
|
try {
|
2025-07-16 12:36:11 +02:00
|
|
|
const organizations = await db.query.organization.findMany({
|
|
|
|
|
where: eq(drizzleDb.schemas.member.userId, userId),
|
2025-05-16 15:54:17 +02:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (organizations.length > 0) {
|
|
|
|
|
return organizations[0].id;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return null;
|
|
|
|
|
} catch (e) {
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
};
|
2025-07-26 14:43:59 +02:00
|
|
|
|
2025-05-16 15:54:17 +02:00
|
|
|
export const createOrganization = async (name: string, slug: string) => {
|
|
|
|
|
try {
|
2025-07-26 14:43:59 +02:00
|
|
|
return await auth.api.createOrganization({
|
2025-09-23 20:35:48 +02:00
|
|
|
headers: await headers(),
|
2025-05-16 15:54:17 +02:00
|
|
|
body: {
|
|
|
|
|
name,
|
|
|
|
|
slug,
|
|
|
|
|
},
|
|
|
|
|
});
|
2025-07-26 14:43:59 +02:00
|
|
|
} catch (e: any) {
|
|
|
|
|
const errorMessage = e?.response?.data?.message || e?.message || "Unknown auth error";
|
|
|
|
|
const status = e?.response?.status || 500;
|
2025-05-16 15:54:17 +02:00
|
|
|
|
2025-07-26 14:43:59 +02:00
|
|
|
console.error("Auth API createOrganization error:", {
|
|
|
|
|
message: errorMessage,
|
|
|
|
|
status,
|
|
|
|
|
raw: e,
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
throw {
|
|
|
|
|
name: "AuthCreateOrganizationError",
|
|
|
|
|
message: errorMessage,
|
|
|
|
|
status,
|
|
|
|
|
cause: e,
|
|
|
|
|
};
|
2025-05-16 15:54:17 +02:00
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2025-07-26 14:43:59 +02:00
|
|
|
export const deleteOrganization = async (organizationId: string) => {
|
|
|
|
|
try {
|
|
|
|
|
return await auth.api.deleteOrganization({
|
|
|
|
|
body: {
|
|
|
|
|
organizationId,
|
|
|
|
|
},
|
|
|
|
|
headers: await headers(),
|
|
|
|
|
});
|
|
|
|
|
} catch (e: any) {
|
|
|
|
|
const errorMessage = e?.response?.data?.message || e?.message || "Unknown auth error";
|
|
|
|
|
const status = e?.response?.status || 500;
|
|
|
|
|
|
|
|
|
|
console.error("Auth API deleteOrganization error:", {
|
|
|
|
|
message: errorMessage,
|
|
|
|
|
status,
|
|
|
|
|
raw: e,
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
throw {
|
|
|
|
|
name: "AuthDeleteOrganizationError",
|
|
|
|
|
message: errorMessage,
|
|
|
|
|
status,
|
|
|
|
|
cause: e,
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
2025-05-16 15:54:17 +02:00
|
|
|
export const checkSlugOrganization = async (slug: string) => {
|
|
|
|
|
try {
|
2025-07-16 12:36:11 +02:00
|
|
|
const {status} = await auth.api.checkOrganizationSlug({
|
2025-05-16 15:54:17 +02:00
|
|
|
headers: await headers(),
|
|
|
|
|
body: {
|
|
|
|
|
slug,
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
return status;
|
|
|
|
|
} catch (e) {
|
|
|
|
|
console.log("err", e);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const getActiveMember = async () => {
|
|
|
|
|
try {
|
|
|
|
|
const member = await auth.api.getActiveMember({
|
|
|
|
|
headers: await headers(),
|
|
|
|
|
});
|
2025-07-16 12:36:11 +02:00
|
|
|
console.log(member);
|
2025-05-16 15:54:17 +02:00
|
|
|
|
2025-11-01 14:50:08 +01:00
|
|
|
return member as MemberWithUser;
|
2025-05-16 15:54:17 +02:00
|
|
|
} catch (e) {
|
|
|
|
|
console.log("err", e);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const setActiveOrganization = async (slug: string) => {
|
|
|
|
|
try {
|
2025-09-23 20:35:48 +02:00
|
|
|
return await auth.api.setActiveOrganization({
|
2025-05-16 15:54:17 +02:00
|
|
|
headers: await headers(),
|
|
|
|
|
body: {
|
|
|
|
|
organizationSlug: slug,
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
} catch (e) {
|
|
|
|
|
console.log("error", e);
|
|
|
|
|
}
|
|
|
|
|
};
|