rhys
rhys
Explore posts from servers
BABetter Auth
Created by rhys on 4/24/2025 in #help
Cookies amongst multiple tenants, subdomains, and custom domains for a SaaS
async trustedOrigins (request) {
const directusAdmin = getDirectusInstance(undefined, DIRECTUS_ADMIN_TOKEN);
const allTenants = await directusAdmin.request(readItems('tenants', {
fields: ['url', 'subdomain'],
}))
const origins: string[] = [
PUBLIC_DOMAIN,
]
if (process.env.NODE_ENV === 'development') origins.push(
`https://www.${PUBLIC_COOKIE_DOMAIN}`)
const allOrigins = allTenants.reduce((acc, tenant) => {
// Handle custom domains stored in the 'url' field
if (typeof tenant.url === 'string' && tenant.url) {
// Ensure the URL is a valid origin format (https://domain.com)
try {
const parsedUrl = new URL(tenant.url);
if (parsedUrl.protocol === 'https:') {
acc.push(parsedUrl.origin);
}
} catch (e) {
console.error(`Invalid tenant URL format: ${tenant.url}`);
}
}
if (tenant.subdomain) {
acc.push(`https://${tenant.subdomain}.${PUBLIC_COOKIE_DOMAIN}`);
}
return acc;
}, origins);
if (process.env.NODE_ENV === 'development') {
console.log('Trusted Origins:', allOrigins)
}
return allOrigins;
},
plugins: [organization({

schema: {
organization: {
modelName: 'tenants',
fields: {
id: 'id',
name: 'title',
slug: 'subdomain',
logo: 'logo',
metadata: 'metadata',
createdAt: 'date_created',
},
},
invitation: {
fields: {
expiresAt: 'expires_at',
inviterId: 'inviter_id',
organizationId: 'organization_id',
teamId: 'team_id',
}
},
member: {
fields: {
organizationId: 'organization_id',
userId: 'user_id',
role: 'role',
status: 'status',
},
},
session: {
fields: {
activeOrganizationId: 'active_organization_id',
}
},
user: {
fields: {
organizationId: 'organization_id',
userId: 'user_id',
}
},
}
})]
});
async trustedOrigins (request) {
const directusAdmin = getDirectusInstance(undefined, DIRECTUS_ADMIN_TOKEN);
const allTenants = await directusAdmin.request(readItems('tenants', {
fields: ['url', 'subdomain'],
}))
const origins: string[] = [
PUBLIC_DOMAIN,
]
if (process.env.NODE_ENV === 'development') origins.push(
`https://www.${PUBLIC_COOKIE_DOMAIN}`)
const allOrigins = allTenants.reduce((acc, tenant) => {
// Handle custom domains stored in the 'url' field
if (typeof tenant.url === 'string' && tenant.url) {
// Ensure the URL is a valid origin format (https://domain.com)
try {
const parsedUrl = new URL(tenant.url);
if (parsedUrl.protocol === 'https:') {
acc.push(parsedUrl.origin);
}
} catch (e) {
console.error(`Invalid tenant URL format: ${tenant.url}`);
}
}
if (tenant.subdomain) {
acc.push(`https://${tenant.subdomain}.${PUBLIC_COOKIE_DOMAIN}`);
}
return acc;
}, origins);
if (process.env.NODE_ENV === 'development') {
console.log('Trusted Origins:', allOrigins)
}
return allOrigins;
},
plugins: [organization({

schema: {
organization: {
modelName: 'tenants',
fields: {
id: 'id',
name: 'title',
slug: 'subdomain',
logo: 'logo',
metadata: 'metadata',
createdAt: 'date_created',
},
},
invitation: {
fields: {
expiresAt: 'expires_at',
inviterId: 'inviter_id',
organizationId: 'organization_id',
teamId: 'team_id',
}
},
member: {
fields: {
organizationId: 'organization_id',
userId: 'user_id',
role: 'role',
status: 'status',
},
},
session: {
fields: {
activeOrganizationId: 'active_organization_id',
}
},
user: {
fields: {
organizationId: 'organization_id',
userId: 'user_id',
}
},
}
})]
});
6 replies
BABetter Auth
Created by rhys on 4/24/2025 in #help
Cookies amongst multiple tenants, subdomains, and custom domains for a SaaS
export const auth = betterAuth({
appName: PUBLIC_APP_NAME,
baseURL: PUBLIC_DOMAIN,
secret: DIRECTUS_SECRET,
emailAndPassword: {
enabled: true,
password: {
hash(password) {
const directus = getDirectusInstance();
return directus.request(generateHash(password))
},
verify({ hash, password}) {
const directus = getDirectusInstance();
return directus.request(verifyHash(password, hash))
},
}
},
advanced: {
database: {
generateId () { return crypto.randomUUID() },
},
crossSubDomainCookies: {
enabled: true,
domain: `.${PUBLIC_COOKIE_DOMAIN}`,
},

cookiePrefix: 'directus',
defaultCookieAttributes: {
secure: true,
httpOnly: true,
sameSite: 'none',
partitioned: true,
},
},
database: new Pool({
connectionString: DB_CONNECTION_STRING,
}),
// database: drizzleAdapter(db, {
// provider: 'pg'
// }),
user: {
modelName: 'directus_users',
fields: {
name: 'first_name',
email: 'email',
image: 'avatar',
createdAt: 'date_created',
updatedAt: 'date_updated',
emailVerified: 'email_verified',
}
},
session: {
modelName: 'directus_sessions',
fields: {
// id has to be initialised with gen_random_uuid() in the database as the default
userId: 'user',
expiresAt: 'expires',
ipAddress: 'ip',
userAgent: 'user_agent',
token: 'token',
createdAt: 'date_created',
updatedAt: 'date_updated',
}
},
verification: {
modelName: 'verification',
fields: {
createdAt: 'date_created',
updatedAt: 'date_updated',
expiresAt: 'expires_at',
value: 'value',
identifier: 'identifier',
},
},
account: {
modelName: 'account',
fields: {
accountId: 'account_id',
userId: 'user_id',
accessToken: 'access_token',
refreshToken: 'refresh_token',
idToken: 'id_token',
providerId: 'provider_id',
accessTokenExpiresAt: "access_token_expires_at",
refreshTokenExpiresAt: "refresh_token_expires_at",
scope: 'scope',
password: 'password',
createdAt: 'date_created',
updatedAt: 'date_updated',
}
},
socialProviders: {
google: {
clientId: GOOGLE_CLIENT_ID,
clientSecret: GOOGLE_CLIENT_SECRET,
mapProfileToUser: (profile) => {
return {
firstName: profile.given_name,
lastName: profile.family_name,
image: profile.picture
};
},
}
},
export const auth = betterAuth({
appName: PUBLIC_APP_NAME,
baseURL: PUBLIC_DOMAIN,
secret: DIRECTUS_SECRET,
emailAndPassword: {
enabled: true,
password: {
hash(password) {
const directus = getDirectusInstance();
return directus.request(generateHash(password))
},
verify({ hash, password}) {
const directus = getDirectusInstance();
return directus.request(verifyHash(password, hash))
},
}
},
advanced: {
database: {
generateId () { return crypto.randomUUID() },
},
crossSubDomainCookies: {
enabled: true,
domain: `.${PUBLIC_COOKIE_DOMAIN}`,
},

cookiePrefix: 'directus',
defaultCookieAttributes: {
secure: true,
httpOnly: true,
sameSite: 'none',
partitioned: true,
},
},
database: new Pool({
connectionString: DB_CONNECTION_STRING,
}),
// database: drizzleAdapter(db, {
// provider: 'pg'
// }),
user: {
modelName: 'directus_users',
fields: {
name: 'first_name',
email: 'email',
image: 'avatar',
createdAt: 'date_created',
updatedAt: 'date_updated',
emailVerified: 'email_verified',
}
},
session: {
modelName: 'directus_sessions',
fields: {
// id has to be initialised with gen_random_uuid() in the database as the default
userId: 'user',
expiresAt: 'expires',
ipAddress: 'ip',
userAgent: 'user_agent',
token: 'token',
createdAt: 'date_created',
updatedAt: 'date_updated',
}
},
verification: {
modelName: 'verification',
fields: {
createdAt: 'date_created',
updatedAt: 'date_updated',
expiresAt: 'expires_at',
value: 'value',
identifier: 'identifier',
},
},
account: {
modelName: 'account',
fields: {
accountId: 'account_id',
userId: 'user_id',
accessToken: 'access_token',
refreshToken: 'refresh_token',
idToken: 'id_token',
providerId: 'provider_id',
accessTokenExpiresAt: "access_token_expires_at",
refreshTokenExpiresAt: "refresh_token_expires_at",
scope: 'scope',
password: 'password',
createdAt: 'date_created',
updatedAt: 'date_updated',
}
},
socialProviders: {
google: {
clientId: GOOGLE_CLIENT_ID,
clientSecret: GOOGLE_CLIENT_SECRET,
mapProfileToUser: (profile) => {
return {
firstName: profile.given_name,
lastName: profile.family_name,
image: profile.picture
};
},
}
},
6 replies
BABetter Auth
Created by rhys on 4/24/2025 in #help
Cookies amongst multiple tenants, subdomains, and custom domains for a SaaS
PUBLIC_DOMAIN is https://localhost:5173 and PUBLIC_COOKIE_DOMAIN is localhost:5173
6 replies
BABetter Auth
Created by Ashwanee Kumar Gupta on 4/22/2025 in #help
redirect_uri starts with http
What's your better auth config?
5 replies
BABetter Auth
Created by rhys on 4/21/2025 in #help
Cookies amongst multiple tenants, subdomains, and custom domains for a SaaS
Good to know we have the same problem. Hopefully there's an easy fix!
9 replies
BABetter Auth
Created by farhan on 4/14/2025 in #help
Stripe Subscription Update Shows Error in Console but Still Works
Have you downgraded to 17.7.0?
10 replies
BABetter Auth
Created by Oleh on 4/22/2025 in #help
Migration Guide from Clerk to Better Auth
Not yet, I suspect it's the sort of thing that's in the works
3 replies
BABetter Auth
Created by rhys on 4/21/2025 in #help
Cookies amongst multiple tenants, subdomains, and custom domains for a SaaS
async trustedOrigins (request) {
const directusAdmin = getDirectusInstance(undefined, DIRECTUS_ADMIN_TOKEN);
const allTenants = await directusAdmin.request(readItems('tenants', {
fields: ['url', 'subdomain'],
}))
const origins: string[] = [
PUBLIC_DOMAIN,
]
if (process.env.NODE_ENV === 'development') origins.push(
`https://www.${PUBLIC_COOKIE_DOMAIN}`)
const allOrigins = allTenants.reduce((acc, tenant) => {
// Handle custom domains stored in the 'url' field
if (typeof tenant.url === 'string' && tenant.url) {
// Ensure the URL is a valid origin format (https://domain.com)
try {
const parsedUrl = new URL(tenant.url);
if (parsedUrl.protocol === 'https:') {
acc.push(parsedUrl.origin);
}
} catch (e) {
console.error(`Invalid tenant URL format: ${tenant.url}`);
}
}
if (tenant.subdomain) {
acc.push(`https://${tenant.subdomain}.${PUBLIC_COOKIE_DOMAIN}`);
}
return acc;
}, origins);
if (process.env.NODE_ENV === 'development') {
console.log('Trusted Origins:', allOrigins)
}
return allOrigins;
},
plugins: [organization({

schema: {
organization: {
modelName: 'tenants',
fields: {
id: 'id',
name: 'title',
slug: 'subdomain',
logo: 'logo',
metadata: 'metadata',
createdAt: 'date_created',
},
},
invitation: {
fields: {
expiresAt: 'expires_at',
inviterId: 'inviter_id',
organizationId: 'organization_id',
teamId: 'team_id',
}
},
member: {
fields: {
organizationId: 'organization_id',
userId: 'user_id',
role: 'role',
status: 'status',
},
},
session: {
fields: {
activeOrganizationId: 'active_organization_id',
}
},
user: {
fields: {
organizationId: 'organization_id',
userId: 'user_id',
}
},
}
})]
});
async trustedOrigins (request) {
const directusAdmin = getDirectusInstance(undefined, DIRECTUS_ADMIN_TOKEN);
const allTenants = await directusAdmin.request(readItems('tenants', {
fields: ['url', 'subdomain'],
}))
const origins: string[] = [
PUBLIC_DOMAIN,
]
if (process.env.NODE_ENV === 'development') origins.push(
`https://www.${PUBLIC_COOKIE_DOMAIN}`)
const allOrigins = allTenants.reduce((acc, tenant) => {
// Handle custom domains stored in the 'url' field
if (typeof tenant.url === 'string' && tenant.url) {
// Ensure the URL is a valid origin format (https://domain.com)
try {
const parsedUrl = new URL(tenant.url);
if (parsedUrl.protocol === 'https:') {
acc.push(parsedUrl.origin);
}
} catch (e) {
console.error(`Invalid tenant URL format: ${tenant.url}`);
}
}
if (tenant.subdomain) {
acc.push(`https://${tenant.subdomain}.${PUBLIC_COOKIE_DOMAIN}`);
}
return acc;
}, origins);
if (process.env.NODE_ENV === 'development') {
console.log('Trusted Origins:', allOrigins)
}
return allOrigins;
},
plugins: [organization({

schema: {
organization: {
modelName: 'tenants',
fields: {
id: 'id',
name: 'title',
slug: 'subdomain',
logo: 'logo',
metadata: 'metadata',
createdAt: 'date_created',
},
},
invitation: {
fields: {
expiresAt: 'expires_at',
inviterId: 'inviter_id',
organizationId: 'organization_id',
teamId: 'team_id',
}
},
member: {
fields: {
organizationId: 'organization_id',
userId: 'user_id',
role: 'role',
status: 'status',
},
},
session: {
fields: {
activeOrganizationId: 'active_organization_id',
}
},
user: {
fields: {
organizationId: 'organization_id',
userId: 'user_id',
}
},
}
})]
});
9 replies
BABetter Auth
Created by rhys on 4/21/2025 in #help
Cookies amongst multiple tenants, subdomains, and custom domains for a SaaS
export const auth = betterAuth({
appName: PUBLIC_APP_NAME,
baseURL: PUBLIC_DOMAIN,
secret: DIRECTUS_SECRET,
emailAndPassword: {
enabled: true,
password: {
hash(password) {
const directus = getDirectusInstance();
return directus.request(generateHash(password))
},
verify({ hash, password}) {
const directus = getDirectusInstance();
return directus.request(verifyHash(password, hash))
},
}
},
advanced: {
database: {
generateId () { return crypto.randomUUID() },
},
crossSubDomainCookies: {
enabled: true,
domain: `.${PUBLIC_COOKIE_DOMAIN}`,
},

cookiePrefix: 'directus',
defaultCookieAttributes: {
secure: true,
httpOnly: true,
sameSite: 'none',
partitioned: true,
},
},
database: new Pool({
connectionString: DB_CONNECTION_STRING,
}),
// database: drizzleAdapter(db, {
// provider: 'pg'
// }),
user: {
modelName: 'directus_users',
fields: {
name: 'first_name',
email: 'email',
image: 'avatar',
createdAt: 'date_created',
updatedAt: 'date_updated',
emailVerified: 'email_verified',
}
},
session: {
modelName: 'directus_sessions',
fields: {
// id has to be initialised with gen_random_uuid() in the database as the default
userId: 'user',
expiresAt: 'expires',
ipAddress: 'ip',
userAgent: 'user_agent',
token: 'token',
createdAt: 'date_created',
updatedAt: 'date_updated',
}
},
verification: {
modelName: 'verification',
fields: {
createdAt: 'date_created',
updatedAt: 'date_updated',
expiresAt: 'expires_at',
value: 'value',
identifier: 'identifier',
},
},
account: {
modelName: 'account',
fields: {
accountId: 'account_id',
userId: 'user_id',
accessToken: 'access_token',
refreshToken: 'refresh_token',
idToken: 'id_token',
providerId: 'provider_id',
accessTokenExpiresAt: "access_token_expires_at",
refreshTokenExpiresAt: "refresh_token_expires_at",
scope: 'scope',
password: 'password',
createdAt: 'date_created',
updatedAt: 'date_updated',
}
},
socialProviders: {
google: {
clientId: GOOGLE_CLIENT_ID,
clientSecret: GOOGLE_CLIENT_SECRET,
mapProfileToUser: (profile) => {
return {
firstName: profile.given_name,
lastName: profile.family_name,
image: profile.picture
};
},
}
},
export const auth = betterAuth({
appName: PUBLIC_APP_NAME,
baseURL: PUBLIC_DOMAIN,
secret: DIRECTUS_SECRET,
emailAndPassword: {
enabled: true,
password: {
hash(password) {
const directus = getDirectusInstance();
return directus.request(generateHash(password))
},
verify({ hash, password}) {
const directus = getDirectusInstance();
return directus.request(verifyHash(password, hash))
},
}
},
advanced: {
database: {
generateId () { return crypto.randomUUID() },
},
crossSubDomainCookies: {
enabled: true,
domain: `.${PUBLIC_COOKIE_DOMAIN}`,
},

cookiePrefix: 'directus',
defaultCookieAttributes: {
secure: true,
httpOnly: true,
sameSite: 'none',
partitioned: true,
},
},
database: new Pool({
connectionString: DB_CONNECTION_STRING,
}),
// database: drizzleAdapter(db, {
// provider: 'pg'
// }),
user: {
modelName: 'directus_users',
fields: {
name: 'first_name',
email: 'email',
image: 'avatar',
createdAt: 'date_created',
updatedAt: 'date_updated',
emailVerified: 'email_verified',
}
},
session: {
modelName: 'directus_sessions',
fields: {
// id has to be initialised with gen_random_uuid() in the database as the default
userId: 'user',
expiresAt: 'expires',
ipAddress: 'ip',
userAgent: 'user_agent',
token: 'token',
createdAt: 'date_created',
updatedAt: 'date_updated',
}
},
verification: {
modelName: 'verification',
fields: {
createdAt: 'date_created',
updatedAt: 'date_updated',
expiresAt: 'expires_at',
value: 'value',
identifier: 'identifier',
},
},
account: {
modelName: 'account',
fields: {
accountId: 'account_id',
userId: 'user_id',
accessToken: 'access_token',
refreshToken: 'refresh_token',
idToken: 'id_token',
providerId: 'provider_id',
accessTokenExpiresAt: "access_token_expires_at",
refreshTokenExpiresAt: "refresh_token_expires_at",
scope: 'scope',
password: 'password',
createdAt: 'date_created',
updatedAt: 'date_updated',
}
},
socialProviders: {
google: {
clientId: GOOGLE_CLIENT_ID,
clientSecret: GOOGLE_CLIENT_SECRET,
mapProfileToUser: (profile) => {
return {
firstName: profile.given_name,
lastName: profile.family_name,
image: profile.picture
};
},
}
},
9 replies
BABetter Auth
Created by rhys on 4/21/2025 in #help
Cookies amongst multiple tenants, subdomains, and custom domains for a SaaS
PUBLIC_DOMAIN is https://localhost:5173 and PUBLIC_COOKIE_DOMAIN is localhost:5173
9 replies
BABetter Auth
Created by rhys on 4/21/2025 in #help
Cookies amongst multiple tenants, subdomains, and custom domains for a SaaS
req headers for sign-up via email:
POST /api/auth/sign-up/email HTTP/2
Host: peggy.localhost:5173
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:137.0) Gecko/20100101 Firefox/137.0
Accept: */*
Accept-Language: en-AU,en-US;q=0.7,en;q=0.3
Accept-Encoding: gzip, deflate, br, zstd
Referer: https://peggy.localhost:5173/signin
content-type: application/json
Content-Length: 186
Origin: https://peggy.localhost:5173
DNT: 1
Connection: keep-alive
Cookie: __Host-__Secure-directus.session_token=Penk9Datqsju9A8dOYso7hGjXgOoqKkf.oc7keEUnUPZ0LTOj2lp%2FrvPe4J5YhbApI2Uhf4heQkw%3D
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-origin
Priority: u=0
Pragma: no-cache
Cache-Control: no-cache
TE: trailers
POST /api/auth/sign-up/email HTTP/2
Host: peggy.localhost:5173
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:137.0) Gecko/20100101 Firefox/137.0
Accept: */*
Accept-Language: en-AU,en-US;q=0.7,en;q=0.3
Accept-Encoding: gzip, deflate, br, zstd
Referer: https://peggy.localhost:5173/signin
content-type: application/json
Content-Length: 186
Origin: https://peggy.localhost:5173
DNT: 1
Connection: keep-alive
Cookie: __Host-__Secure-directus.session_token=Penk9Datqsju9A8dOYso7hGjXgOoqKkf.oc7keEUnUPZ0LTOj2lp%2FrvPe4J5YhbApI2Uhf4heQkw%3D
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-origin
Priority: u=0
Pragma: no-cache
Cache-Control: no-cache
TE: trailers
response headers:
HTTP/2 200
access-control-allow-origin: *
vary: Origin
content-type: application/json
set-cookie: __Secure-directus.session_token=onz6fOWLpPbJhf2yCeh57tqIjOsTe6xM.jeemRnvxeWtSbTmnA1o%2B%2F95yTDLGrjiqbjAO6iMjRs8%3D; Max-Age=604800; Domain=.localhost:5173; Path=/; HttpOnly; Secure; SameSite=None; Partitioned
date: Mon, 21 Apr 2025 11:20:09 GMT
X-Firefox-Spdy: h2
HTTP/2 200
access-control-allow-origin: *
vary: Origin
content-type: application/json
set-cookie: __Secure-directus.session_token=onz6fOWLpPbJhf2yCeh57tqIjOsTe6xM.jeemRnvxeWtSbTmnA1o%2B%2F95yTDLGrjiqbjAO6iMjRs8%3D; Max-Age=604800; Domain=.localhost:5173; Path=/; HttpOnly; Secure; SameSite=None; Partitioned
date: Mon, 21 Apr 2025 11:20:09 GMT
X-Firefox-Spdy: h2
9 replies
BABetter Auth
Created by rhys on 4/12/2025 in #help
Output debug mode?
Hot damn! It's at the very least inserted the dummy data in the user table in the db- I get
error {"length":130,"name":"error","severity":"ERROR","code":"42703","position":"38","file":"parse_target.c","line":"1065","routine":"checkInsertTargets"}
error {"length":130,"name":"error","severity":"ERROR","code":"42703","position":"38","file":"parse_target.c","line":"1065","routine":"checkInsertTargets"}
. The account table is empty, but this is well and truly progress.
35 replies
BABetter Auth
Created by rhys on 4/12/2025 in #help
Output debug mode?
If database is an object, how do I pass the postgres pool? i.e.
database: {
generateId: false,
db: new Pool({
connectionString: DATABASE_URL
})
},
database: {
generateId: false,
db: new Pool({
connectionString: DATABASE_URL
})
},
35 replies
BABetter Auth
Created by rhys on 4/12/2025 in #help
Output debug mode?
I think the docs are just a touch out of date, generateId has shifted to database according to the intellisense
35 replies
BABetter Auth
Created by s on 4/12/2025 in #help
guys, is it possible to do with better-aauth??
12 replies
BABetter Auth
Created by rhys on 4/12/2025 in #help
Output debug mode?
Ok! That worked too. Now, it's returning 2025-04-13T00:04:21.563Z ERROR [Better Auth]: Failed to create user error: invalid input syntax for type uuid: "b7g00pstBsS5FGSuTitnYGpkIxe2RBzK". The id generated by BetterAuth likely doesn't jive with the uuid PK. I can see the generateId function that's being called as part of the create user flow is a pretty straightforward wrapper, is there any possibility that this could be extended to allow for uuid use?
35 replies
BABetter Auth
Created by rhys on 4/12/2025 in #help
Output debug mode?
Thanks so much! I'll give that a shot.
35 replies
BABetter Auth
Created by s on 4/12/2025 in #help
guys, is it possible to do with better-aauth??
As Nico says, hooks sound like they'd do the trick. Just fyi it's not great manners to ping maintainers directly- they literally just pushed a new release, and are very busy.
12 replies
BABetter Auth
Created by rhys on 4/12/2025 in #help
Output debug mode?
Nuts. Is there any way to coerce it? I don't think directus supports it being a Date.
35 replies
BABetter Auth
Created by rhys on 4/12/2025 in #help
Output debug mode?
Ahh yeah, you're one hundred percent right, looks like it is a drizzle thing. And updating to the beta has resulted in a fun new error-
bash ERROR [Better Auth]: Failed to create user TypeError [ERR_INVALID_ARG_TYPE]: The "string" argument must be of type string or an instance of Buffer or ArrayBuffer. Received an instance of Date
bash ERROR [Better Auth]: Failed to create user TypeError [ERR_INVALID_ARG_TYPE]: The "string" argument must be of type string or an instance of Buffer or ArrayBuffer. Received an instance of Date
Looks like the type is wrong for one of the columns on the users table, but the only two are date_created and date_updated, which are timestamp({ mode: 'string' }).
export const directus_users = pgTable("directus_users", {
id: uuid().primaryKey().notNull(),
first_name: varchar({ length: 50 }),
last_name: varchar({ length: 50 }),
email: varchar({ length: 128 }),
password: varchar({ length: 255 }),
location: varchar({ length: 255 }),
title: varchar({ length: 50 }),
description: text(),
tags: json(),
avatar: uuid(),
language: varchar({ length: 255 }).default(sql`NULL`),
tfa_secret: varchar({ length: 255 }),
status: varchar({ length: 16 }).default('active').notNull(),
role: uuid(),
token: varchar({ length: 255 }),
last_access: timestamp({ withTimezone: true, mode: 'string' }),
last_page: varchar({ length: 255 }),
provider: varchar({ length: 128 }).default('default').notNull(),
external_identifier: varchar({ length: 255 }),
auth_data: json(),
email_notifications: boolean().default(true),
appearance: varchar({ length: 255 }),
theme_dark: varchar({ length: 255 }),
theme_light: varchar({ length: 255 }),
theme_light_overrides: json(),
theme_dark_overrides: json(),
short_bio: text(),
biography: text(),
hero_image: uuid(),
is_group: boolean().default(false),
social_media: json(),
date_created: timestamp({ mode: 'string' }),
date_updated: timestamp({ mode: 'string' }),
email_verified: boolean().default(false).notNull(),
}, (table) => [
foreignKey({
columns: [table.hero_image],
foreignColumns: [directus_files.id],
name: "directus_users_hero_image_foreign"
}).onDelete("set null"),
foreignKey({
columns: [table.role],
foreignColumns: [directus_roles.id],
name: "directus_users_role_foreign"
}).onDelete("set null"),
unique("directus_users_email_unique").on(table.email),
unique("directus_users_token_unique").on(table.token),
unique("directus_users_external_identifier_unique").on(table.external_identifier),
]);
export const directus_users = pgTable("directus_users", {
id: uuid().primaryKey().notNull(),
first_name: varchar({ length: 50 }),
last_name: varchar({ length: 50 }),
email: varchar({ length: 128 }),
password: varchar({ length: 255 }),
location: varchar({ length: 255 }),
title: varchar({ length: 50 }),
description: text(),
tags: json(),
avatar: uuid(),
language: varchar({ length: 255 }).default(sql`NULL`),
tfa_secret: varchar({ length: 255 }),
status: varchar({ length: 16 }).default('active').notNull(),
role: uuid(),
token: varchar({ length: 255 }),
last_access: timestamp({ withTimezone: true, mode: 'string' }),
last_page: varchar({ length: 255 }),
provider: varchar({ length: 128 }).default('default').notNull(),
external_identifier: varchar({ length: 255 }),
auth_data: json(),
email_notifications: boolean().default(true),
appearance: varchar({ length: 255 }),
theme_dark: varchar({ length: 255 }),
theme_light: varchar({ length: 255 }),
theme_light_overrides: json(),
theme_dark_overrides: json(),
short_bio: text(),
biography: text(),
hero_image: uuid(),
is_group: boolean().default(false),
social_media: json(),
date_created: timestamp({ mode: 'string' }),
date_updated: timestamp({ mode: 'string' }),
email_verified: boolean().default(false).notNull(),
}, (table) => [
foreignKey({
columns: [table.hero_image],
foreignColumns: [directus_files.id],
name: "directus_users_hero_image_foreign"
}).onDelete("set null"),
foreignKey({
columns: [table.role],
foreignColumns: [directus_roles.id],
name: "directus_users_role_foreign"
}).onDelete("set null"),
unique("directus_users_email_unique").on(table.email),
unique("directus_users_token_unique").on(table.token),
unique("directus_users_external_identifier_unique").on(table.external_identifier),
]);
35 replies