BA
Better Auth•5mo ago
In&Out

New to better-auth

Hey folks, since better-auth generates own tables, can i modify that? I want it to be linked to my own users table, would that do anything bad?
20 Replies
In&Out
In&OutOP•5mo ago
Like, these are the tables that are generated by better-auth
CREATE TABLE "user"
(
"id" TEXT NOT NULL PRIMARY KEY,
"name" TEXT NOT NULL,
"email" TEXT NOT NULL UNIQUE,
"emailverified" BOOLEAN NOT NULL,
"image" TEXT,
"createdat" TIMESTAMP NOT NULL,
"updatedat" TIMESTAMP NOT NULL,
"username" TEXT UNIQUE,
"displayusername" TEXT
);

CREATE TABLE "session"
(
"id" TEXT NOT NULL PRIMARY KEY,
"expiresat" TIMESTAMP NOT NULL,
"token" TEXT NOT NULL UNIQUE,
"createdat" TIMESTAMP NOT NULL,
"updatedat" TIMESTAMP NOT NULL,
"ipaddress" TEXT,
"useragent" TEXT,
"userid" TEXT NOT NULL REFERENCES "user" ("id")
);

CREATE TABLE "account"
(
"id" TEXT NOT NULL PRIMARY KEY,
"accountid" TEXT NOT NULL,
"providerid" TEXT NOT NULL,
"userid" TEXT NOT NULL REFERENCES "user" ("id"),
"accesstoken" TEXT,
"refreshtoken" TEXT,
"idtoken" TEXT,
"accesstokenexpiresat" TIMESTAMP,
"refreshtokenexpiresat" TIMESTAMP,
"scope" TEXT,
"password" TEXT,
"createdat" TIMESTAMP NOT NULL,
"updatedat" TIMESTAMP NOT NULL
);

CREATE TABLE "verification"
(
"id" TEXT NOT NULL PRIMARY KEY,
"identifier" TEXT NOT NULL,
"value" TEXT NOT NULL,
"expiresat" TIMESTAMP NOT NULL,
"createdat" TIMESTAMP,
"updatedat" TIMESTAMP
);
CREATE TABLE "user"
(
"id" TEXT NOT NULL PRIMARY KEY,
"name" TEXT NOT NULL,
"email" TEXT NOT NULL UNIQUE,
"emailverified" BOOLEAN NOT NULL,
"image" TEXT,
"createdat" TIMESTAMP NOT NULL,
"updatedat" TIMESTAMP NOT NULL,
"username" TEXT UNIQUE,
"displayusername" TEXT
);

CREATE TABLE "session"
(
"id" TEXT NOT NULL PRIMARY KEY,
"expiresat" TIMESTAMP NOT NULL,
"token" TEXT NOT NULL UNIQUE,
"createdat" TIMESTAMP NOT NULL,
"updatedat" TIMESTAMP NOT NULL,
"ipaddress" TEXT,
"useragent" TEXT,
"userid" TEXT NOT NULL REFERENCES "user" ("id")
);

CREATE TABLE "account"
(
"id" TEXT NOT NULL PRIMARY KEY,
"accountid" TEXT NOT NULL,
"providerid" TEXT NOT NULL,
"userid" TEXT NOT NULL REFERENCES "user" ("id"),
"accesstoken" TEXT,
"refreshtoken" TEXT,
"idtoken" TEXT,
"accesstokenexpiresat" TIMESTAMP,
"refreshtokenexpiresat" TIMESTAMP,
"scope" TEXT,
"password" TEXT,
"createdat" TIMESTAMP NOT NULL,
"updatedat" TIMESTAMP NOT NULL
);

CREATE TABLE "verification"
(
"id" TEXT NOT NULL PRIMARY KEY,
"identifier" TEXT NOT NULL,
"value" TEXT NOT NULL,
"expiresat" TIMESTAMP NOT NULL,
"createdat" TIMESTAMP,
"updatedat" TIMESTAMP
);
But my table is gonna be something like this
CREATE TABLE users (
user_id uuid NOT NULL UNIQUE PRIMARY KEY,
email TEXT UNIQUE NOT NULL,
hashed_password TEXT NOT NULL, -- Hash manually
user_name TEXT,
role TEXT,
ibk_slug TEXT, -- SANITIZE IT IN NEXTJS
category TEXT,
created_at TIMESTAMPTZ DEFAULT now(),
raw_user_meta_data JSONB DEFAULT '{}'::jsonb -- see example above
);

-- YOU GOTTA MAKE INDEXES INSTEAD OF constraint's, not allowed
CREATE UNIQUE INDEX unique_ibk_slug_for_superadmin
ON users (ibk_slug)
WHERE role = 'superadmin';
-- or this
create unique INDEX IF not exists unique_ibk_slug_for_superadmins on public.users using btree (ibk_slug)
where
(role = 'superadmin'::text);
CREATE TABLE users (
user_id uuid NOT NULL UNIQUE PRIMARY KEY,
email TEXT UNIQUE NOT NULL,
hashed_password TEXT NOT NULL, -- Hash manually
user_name TEXT,
role TEXT,
ibk_slug TEXT, -- SANITIZE IT IN NEXTJS
category TEXT,
created_at TIMESTAMPTZ DEFAULT now(),
raw_user_meta_data JSONB DEFAULT '{}'::jsonb -- see example above
);

-- YOU GOTTA MAKE INDEXES INSTEAD OF constraint's, not allowed
CREATE UNIQUE INDEX unique_ibk_slug_for_superadmin
ON users (ibk_slug)
WHERE role = 'superadmin';
-- or this
create unique INDEX IF not exists unique_ibk_slug_for_superadmins on public.users using btree (ibk_slug)
where
(role = 'superadmin'::text);
nikatune
nikatune•5mo ago
you can modify it
Ping
Ping•5mo ago
Yeah we recommend modifying it to suit your needs.
In&Out
In&OutOP•5mo ago
okay thanks you two i need help please this is my table now
CREATE TABLE "user" (
id TEXT PRIMARY KEY,
name TEXT NOT NULL,
email TEXT NOT NULL UNIQUE,
emailVerified BOOLEAN NOT NULL DEFAULT false,
image TEXT,
createdAt TIMESTAMP NOT NULL DEFAULT now(),
updatedAt TIMESTAMP NOT NULL DEFAULT now(),
user_name TEXT,
role TEXT,
ibk_slug TEXT,
category TEXT,
raw_user_meta_data JSONB DEFAULT '{}'::jsonb
);
CREATE TABLE "user" (
id TEXT PRIMARY KEY,
name TEXT NOT NULL,
email TEXT NOT NULL UNIQUE,
emailVerified BOOLEAN NOT NULL DEFAULT false,
image TEXT,
createdAt TIMESTAMP NOT NULL DEFAULT now(),
updatedAt TIMESTAMP NOT NULL DEFAULT now(),
user_name TEXT,
role TEXT,
ibk_slug TEXT,
category TEXT,
raw_user_meta_data JSONB DEFAULT '{}'::jsonb
);
How can i extend it? in here,
export const auth = betterAuth({
database: new Pool({
connectionString: process.env.DATABASE_URL,
}),
emailAndPassword: {
enabled: true,
},
user:{
additionalFields:{

}
},
plugins: [nextCookies()],
});
export const auth = betterAuth({
database: new Pool({
connectionString: process.env.DATABASE_URL,
}),
emailAndPassword: {
enabled: true,
},
user:{
additionalFields:{

}
},
plugins: [nextCookies()],
});
i dont get it looking from this link i want role to be default to "superadmin"
Ping
Ping•5mo ago
Add the role field to your additionalFields, within that you can pass a defaultValue.
Ping
Ping•5mo ago
Like this
No description
In&Out
In&OutOP•5mo ago
i want to pass other fields as well tho
Ping
Ping•5mo ago
Then add other fields
In&Out
In&OutOP•5mo ago
alr alr lemme see another question, i will have 2 user forms, one will be normal one and another will be for inside dashboard, i want to make a role, if you signed up inside /signup, your role will automatically be "superadmin", but if you made user from /dashboard/moderators, you get role "editor", how would i do that?
Ping
Ping•5mo ago
* Add the admin plugin from Better-auth docs * I assume your moderators are essentially site admins if they're able to make new users - in such case you can use the admin plugin to call the authClient.admin.createUser to make a new user, and from there you can also pass a role which can be the editor. Note that if you're using the admin plugin, the role will exist by default, so you don't need the additionalFields for a role. You will however have to look into the admin docs fully to ensure you understand how it works, as well as how to set default roles etc.
Admin | Better Auth
Admin plugin for Better Auth
In&Out
In&OutOP•5mo ago
great, thats it, thank you one more thing
export async function registerUser(prevState: any, formData: FormData) {
const email = formData.get("email")?.toString().trim();
const password = formData.get("password")?.toString();
const userName = formData.get("username")?.toString().trim();
const category = formData.get("category")?.toString();

if (!email || !password || !userName || !category) {
return { error: "All fields are required." };
}

const ibk_slug = userName
.toLowerCase()
.replace(/\s+/g, "_")
.replace(/[^\w_]/g, "");

const result = await auth.api.signUpEmail({
body: {
email,
password,
name: userName,
ibk_slug,
category,
},
});
console.log(result)
if ("error" in result) {
console.error("Sign-in error:", result.error);
return { error: result.error.message }
}

redirect(`/dashboard/${ibk_slug}`);
}
export async function registerUser(prevState: any, formData: FormData) {
const email = formData.get("email")?.toString().trim();
const password = formData.get("password")?.toString();
const userName = formData.get("username")?.toString().trim();
const category = formData.get("category")?.toString();

if (!email || !password || !userName || !category) {
return { error: "All fields are required." };
}

const ibk_slug = userName
.toLowerCase()
.replace(/\s+/g, "_")
.replace(/[^\w_]/g, "");

const result = await auth.api.signUpEmail({
body: {
email,
password,
name: userName,
ibk_slug,
category,
},
});
console.log(result)
if ("error" in result) {
console.error("Sign-in error:", result.error);
return { error: result.error.message }
}

redirect(`/dashboard/${ibk_slug}`);
}
result.error.message doesnt exist how can i return errors
Ping
Ping•5mo ago
auth.api will throw an error, not return {data, error} You need to use a try catch block
In&Out
In&OutOP•5mo ago
export const auth = betterAuth({
database: new Pool({
connectionString: process.env.DATABASE_URL,
}),
emailAndPassword: {
enabled: true,
},
onAPIError: {
throw: true,
onError: (error, ctx) => {
console.error("Auth error:", error);
},
errorURL: "/error",
},
export const auth = betterAuth({
database: new Pool({
connectionString: process.env.DATABASE_URL,
}),
emailAndPassword: {
enabled: true,
},
onAPIError: {
throw: true,
onError: (error, ctx) => {
console.error("Auth error:", error);
},
errorURL: "/error",
},
like this? if no, can you give me an example or something please im kinda new to this
Ping
Ping•5mo ago
try {
auth.api.signInEmail()
} catch (error) {

}
try {
auth.api.signInEmail()
} catch (error) {

}
@In&Out Also try your best to avoid using auth.api unless absolutely necessary, by the way
In&Out
In&OutOP•5mo ago
how so? i just want errors, like if user alraedy exists and stuff like that im using auth.ts not auth-client if it matters nevermind, figured it out
The Untraceable
The Untraceable•5mo ago
That's for server side use, if you want nice errors (as I have been doing so), I use authClient which does provide {data, error}. The types are nicely set for intellisense so it works like a charm
In&Out
In&OutOP•5mo ago
thank you yeah yeah, just saw that, tho docs were bit rough on that
Ping
Ping•5mo ago
Once 1.3 is released hopefully the docs will be more clear about this Sorry for the late replies by the way, I noticed you pinged me a few times yesterday - I had a dreadful headache so I went to sleep early 😅
In&Out
In&OutOP•5mo ago
no worries mate, i figured out the stuff i asked for anyways cant wait docs arent bad but are inconsistent like this for example, i didnt see this anywhere in docs, probably was there but still idk,
plugins: [
nextCookies(),
admin({
defaultRole: "admin",
}),
],
});
plugins: [
nextCookies(),
admin({
defaultRole: "admin",
}),
],
});
had more examples but i forgot them ngl lol

Did you find this page helpful?