NextAuth password migration

I'm currently migrating from NextAuth. Is it possible to retain the existing passwords or otherwise customize the password hashing process? how to handle password migration ?
6 Replies
Chandra
Chandra2mo ago
@parweb do you got the solution?
parweb
parwebOP2mo ago
Kinda, I didn’t implement it yet, but the gist of it is to override the hashing function of better auth
Chandra
Chandra2mo ago
what about migrating passwords? next auth store password in user table but better auth in credential
bekacru
bekacru2mo ago
you can copy the password hash to where better auth expects it to be. And you can implement custom password hashing, if it's not scrypt or you have different configuration.
Chandra
Chandra2mo ago
@bekacru I wrote this migration script, I have 190 users. so just need you to verify the code:
import { generateUUID } from '@/lib/chat/utils';
import { PrismaClient, User } from '@prisma/client';

const prisma = new PrismaClient();

async function main() {
console.log('Migrating to better auth');
const users = (await prisma.user.findRaw({})) as unknown as {
_id: {
$oid: string;
};
emailVerified: Date;
}[];
const verifiyUsers = users.map((user) => ({
id: user._id?.$oid,
emailVerified: !!user.emailVerified,
}));
console.log('Users', verifiyUsers.slice(0, 4));

for (const user of verifiyUsers) {
await prisma.user.update({
where: { id: user.id },
data: { emailVerified: user.emailVerified },
});
}
const date = new Date();
const accounts = (await prisma.account.findRaw({})) as unknown as {
_id: {
$oid: string;
};
scope?: string;
}[];

const updateaccounts = accounts.map((acc) => ({
...acc,
id: acc._id?.$oid,
createdAt: date,
scope: acc.scope?.startsWith('openid ')
? acc.scope.replace('openid ', '')
: acc.scope,
}));

console.log(
'Accounts',
updateaccounts.filter((acc) => !acc.id),
);

for (const account of updateaccounts) {
await prisma.account.update({
where: { id: account.id },
data: { createdAt: date, scope: account.scope },
});
}

const userForAccounts = await prisma.user.findMany();

await prisma.account.createMany({
data: userForAccounts.map((user) => ({
id: generateUUID(),
accountId: user.id,
userId: user.id,
password: user.password,
providerId: 'credential',
})),
});

console.log('Migrate completed');
}

void main()
.then(async () => {
await prisma.$disconnect();
})
.catch(async (e) => {
// eslint-disable-next-line no-console
console.error(e);
await prisma.$disconnect();
process.exit(1);
});
import { generateUUID } from '@/lib/chat/utils';
import { PrismaClient, User } from '@prisma/client';

const prisma = new PrismaClient();

async function main() {
console.log('Migrating to better auth');
const users = (await prisma.user.findRaw({})) as unknown as {
_id: {
$oid: string;
};
emailVerified: Date;
}[];
const verifiyUsers = users.map((user) => ({
id: user._id?.$oid,
emailVerified: !!user.emailVerified,
}));
console.log('Users', verifiyUsers.slice(0, 4));

for (const user of verifiyUsers) {
await prisma.user.update({
where: { id: user.id },
data: { emailVerified: user.emailVerified },
});
}
const date = new Date();
const accounts = (await prisma.account.findRaw({})) as unknown as {
_id: {
$oid: string;
};
scope?: string;
}[];

const updateaccounts = accounts.map((acc) => ({
...acc,
id: acc._id?.$oid,
createdAt: date,
scope: acc.scope?.startsWith('openid ')
? acc.scope.replace('openid ', '')
: acc.scope,
}));

console.log(
'Accounts',
updateaccounts.filter((acc) => !acc.id),
);

for (const account of updateaccounts) {
await prisma.account.update({
where: { id: account.id },
data: { createdAt: date, scope: account.scope },
});
}

const userForAccounts = await prisma.user.findMany();

await prisma.account.createMany({
data: userForAccounts.map((user) => ({
id: generateUUID(),
accountId: user.id,
userId: user.id,
password: user.password,
providerId: 'credential',
})),
});

console.log('Migrate completed');
}

void main()
.then(async () => {
await prisma.$disconnect();
})
.catch(async (e) => {
// eslint-disable-next-line no-console
console.error(e);
await prisma.$disconnect();
process.exit(1);
});
I tested it works, but just to double check. I have updated the has fn;
Chandra
Chandra5w ago
does it feel ok to you?

Did you find this page helpful?