Falling back to database queries

Sometimes, Lucia’s API isn’t enough. For example, you might want to create a user within a database transaction. The great thing about Lucia is that you can always fallback to raw database queries when you need to. And since a lot of Lucia’s API is really just a light wrapper around database queries, it’s often easy to implement.

That said, we discourage replacing any APIs related to session management, especially since at that point you might be better off replacing Lucia entirely.

Create users and keys#

Auth.createUser() creates both a key and user in a database transaction. Creating a user is pretty straightforward. The user id is 15 characters long when using the default configuration.

import { generateRandomString } from "lucia/utils";

// implement `Auth.createUser()`
// execute all in a single transaction
await db.transaction((trx) => {
	const userId = generateRandomString(15);
	await trx.user.insert({
		id: userId,
		// any additional column for user attributes
		username
	});

	// TODO: create key
});

Keys are bit more complicated. The key id is a combination of the provider id and provider user id. You can create it using createKeyId(). For hashed_password, you can use generateLuciaPasswordHash() to hash passwords using Lucia’s default hashing function or set it to null.

This part is exactly the same for Auth.createKey().

import { generateRandomString, generateLuciaPasswordHash } from "lucia/utils";
import { createKeyId } from "lucia";

// execute all in a single transaction
await db.transaction((trx) => {
	const userId = generateRandomString(15); //
	await trx.user.insert({
		id: userId,
		username
	});

	await trx.key.insert({
		id: createKeyId("username", username),
		user_id: userId,
		hashed_password: await generateLuciaPasswordHash(password)
	});
});

Transform database objects#

Lucia’s Auth instance includes methods to transform database query results:

import { auth } from "./lucia.js";

const databaseUser = await db.user.get(userId);
const user = auth.transformDatabaseUser(databaseUser);