mirror of
https://github.com/better-auth/better-auth.git
synced 2026-07-26 02:16:23 -05:00
docs: fix auth0 migration guide for v5 (#10273)
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> Co-authored-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: Maxwell <ping-maxwell@users.noreply.github.com>
This commit is contained in:
co-authored by
greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
Cursor Agent
Maxwell
parent
6f3ba45639
commit
fd6b8c13bb
@@ -6,7 +6,7 @@ description: A step-by-step guide to transitioning from Auth0 to Better Auth.
|
||||
In this guide, we'll walk through the steps to migrate a project from Auth0 to Better Auth — including email/password with proper hashing, social/external accounts, two-factor authentication, and more.
|
||||
|
||||
<Callout type="warn">
|
||||
This migration will invalidate all active sessions. This guide doesn't currently show you how to migrate Organizations but it should be possible with additional steps and the [Organization](/docs/plugins/organization) Plugin.
|
||||
This migration will invalidate all active sessions. When the [Organization](/docs/plugins/organization) plugin is enabled, the script will also attempt a best-effort migration of Auth0 Organizations, their members, and per-member roles. Invitations and enabled-connection configuration are not migrated and should be reconfigured manually in Better Auth.
|
||||
</Callout>
|
||||
|
||||
## Before You Begin
|
||||
@@ -346,7 +346,7 @@ Before starting the migration process, set up Better Auth in your project. Follo
|
||||
tokenType: identity.token_type,
|
||||
refreshToken: identity.refresh_token,
|
||||
accessTokenExpiresAt: identity.expires_in ? new Date(Date.now() + identity.expires_in * 1000) : undefined,
|
||||
// if you are enterprise user, you can get the refresh tokens or all the tokensets - auth0Client.users.getAllTokensets
|
||||
// if you are enterprise user, you can get the refresh tokens or all the tokensets - auth0Client.users.federatedConnectionsTokensets.list(auth0User.user_id)
|
||||
refreshTokenExpiresAt: identity.refresh_token_expires_in ? new Date(Date.now() + identity.refresh_token_expires_in * 1000) : undefined,
|
||||
|
||||
scope: identity.scope,
|
||||
@@ -363,7 +363,7 @@ Before starting the migration process, set up Better Auth in your project. Follo
|
||||
data: {
|
||||
id: `${auth0User.user_id}|${identity.provider}|${identity.user_id}`,
|
||||
userId: userId,
|
||||
password: migratePassword(auth0User),
|
||||
password: await migratePassword(auth0User),
|
||||
providerId: providerId,
|
||||
accountId: identity.user_id,
|
||||
accessToken: identity.access_token,
|
||||
@@ -389,8 +389,15 @@ Before starting the migration process, set up Better Auth in your project. Follo
|
||||
|
||||
async function migrateOrganizations(ctx: any) {
|
||||
try {
|
||||
const organizations = await auth0Client.organizations.getAll();
|
||||
for (const org of organizations.data || []) {
|
||||
const organizations: any[] = [];
|
||||
let orgPage = await auth0Client.organizations.list({ take: 50 });
|
||||
organizations.push(...orgPage.data);
|
||||
while (orgPage.hasNextPage()) {
|
||||
orgPage = await orgPage.getNextPage();
|
||||
organizations.push(...orgPage.data);
|
||||
}
|
||||
|
||||
for (const org of organizations) {
|
||||
try {
|
||||
await ctx.adapter.create({
|
||||
model: "organization",
|
||||
@@ -404,14 +411,29 @@ Before starting the migration process, set up Better Auth in your project. Follo
|
||||
},
|
||||
forceAllowId: true
|
||||
});
|
||||
const members = await auth0Client.organizations.getMembers({ id: org.id });
|
||||
for (const member of members.data || []) {
|
||||
|
||||
const members: any[] = [];
|
||||
let memberPage = await auth0Client.organizations.members.list(org.id, { take: 50 });
|
||||
members.push(...memberPage.data);
|
||||
while (memberPage.hasNextPage()) {
|
||||
memberPage = await memberPage.getNextPage();
|
||||
members.push(...memberPage.data);
|
||||
}
|
||||
|
||||
for (const member of members) {
|
||||
try {
|
||||
const userRoles = await auth0Client.organizations.getMemberRoles({
|
||||
id: org.id,
|
||||
user_id: member.user_id
|
||||
});
|
||||
const role = mapAuth0RoleToBetterAuthRole(userRoles.data?.map(r => r.name) || []);
|
||||
const userRoles: any[] = [];
|
||||
let rolePage = await auth0Client.organizations.members.roles.list(
|
||||
org.id,
|
||||
member.user_id,
|
||||
{ per_page: 50, page: 0 }
|
||||
);
|
||||
userRoles.push(...(rolePage.data || []));
|
||||
while (rolePage.hasNextPage()) {
|
||||
rolePage = await rolePage.getNextPage();
|
||||
userRoles.push(...(rolePage.data || []));
|
||||
}
|
||||
const role = mapAuth0RoleToBetterAuthRole(userRoles.map(r => r.name));
|
||||
await ctx.adapter.create({
|
||||
model: "member",
|
||||
data: {
|
||||
@@ -447,28 +469,21 @@ Before starting the migration process, set up Better Auth in your project. Follo
|
||||
const isAdminEnabled = ctx.options?.plugins?.find(plugin => plugin.id === "admin");
|
||||
const isUsernameEnabled = ctx.options?.plugins?.find(plugin => plugin.id === "username");
|
||||
const isOrganizationEnabled = ctx.options?.plugins?.find(plugin => plugin.id === "organization");
|
||||
const perPage = 100;
|
||||
const auth0Users: any[] = [];
|
||||
let pageNumber = 0;
|
||||
|
||||
while (true) {
|
||||
try {
|
||||
const params = {
|
||||
per_page: perPage,
|
||||
page: pageNumber,
|
||||
include_totals: true,
|
||||
};
|
||||
const response = (await auth0Client.users.getAll(params)).data as any;
|
||||
const users = response.users || [];
|
||||
if (users.length === 0) break;
|
||||
auth0Users.push(...users);
|
||||
pageNumber++;
|
||||
|
||||
if (users.length < perPage) break;
|
||||
} catch (error) {
|
||||
console.error('Error fetching users:', error);
|
||||
break;
|
||||
try {
|
||||
let userPage = await auth0Client.users.list({
|
||||
per_page: 100,
|
||||
page: 0,
|
||||
include_totals: true,
|
||||
});
|
||||
auth0Users.push(...userPage.data);
|
||||
while (userPage.hasNextPage()) {
|
||||
userPage = await userPage.getNextPage();
|
||||
auth0Users.push(...userPage.data);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error fetching users:', error);
|
||||
}
|
||||
|
||||
|
||||
@@ -520,7 +535,6 @@ Before starting the migration process, set up Better Auth in your project. Follo
|
||||
if (isOrganizationEnabled) {
|
||||
await migrateOrganizations(ctx);
|
||||
}
|
||||
// the reset of migration will be here.
|
||||
console.log('Migration completed successfully');
|
||||
} catch (error) {
|
||||
console.error('Migration failed:', error);
|
||||
@@ -695,7 +709,7 @@ The script includes a basic role mapping function (`mapAuth0RoleToBetterAuthRole
|
||||
|
||||
### Rate Limiting
|
||||
|
||||
The migration script includes pagination to handle large numbers of users. Adjust the `perPage` value based on your needs and Auth0's rate limits.
|
||||
The migration script includes pagination to handle large numbers of users. Adjust the `per_page` (offset pagination) and `take` (checkpoint pagination) values passed to the Auth0 `list()` calls based on your needs and Auth0's rate limits.
|
||||
|
||||
## Wrapping Up
|
||||
|
||||
|
||||
Reference in New Issue
Block a user