How to trigger refresh/update of session if user info changed
I made a plugin to store some custom user info
My Current session settings are:
So whenever I update the user data, like approving the user data then the user wont see it reflected until the session token is refreshed after 1 day.
Currently the way I am handling it is by revoking all user sessions which is a sloppy approach as it signs out all the users.
Note : I am also using Secondary Storage(Redis)
import type { BetterAuthPlugin } from 'better-auth';
export const userInfoPlugin = () => {
return {
id: 'additional_user_info',
schema: {
user: {
fields: {
is_approved: {
type: 'boolean',
defaultValue: false
},
super_admin: {
type: 'boolean',
defaultValue: false
}
}
}
}
} satisfies BetterAuthPlugin;
};import type { BetterAuthPlugin } from 'better-auth';
export const userInfoPlugin = () => {
return {
id: 'additional_user_info',
schema: {
user: {
fields: {
is_approved: {
type: 'boolean',
defaultValue: false
},
super_admin: {
type: 'boolean',
defaultValue: false
}
}
}
}
} satisfies BetterAuthPlugin;
};My Current session settings are:
session: {
cookieCache: {
enabled: true,
maxAge: COOKIE_CACHE_TIME_MS / 1000
},
expiresIn: 60 * 60 * 24 * 20, // 20 days
updateAge: 60 * 60 * 24 * 1 // 1 day (every 1 day the session expiration is updated)
}session: {
cookieCache: {
enabled: true,
maxAge: COOKIE_CACHE_TIME_MS / 1000
},
expiresIn: 60 * 60 * 24 * 20, // 20 days
updateAge: 60 * 60 * 24 * 1 // 1 day (every 1 day the session expiration is updated)
}So whenever I update the user data, like approving the user data then the user wont see it reflected until the session token is refreshed after 1 day.
Currently the way I am handling it is by revoking all user sessions which is a sloppy approach as it signs out all the users.
Note : I am also using Secondary Storage(Redis)
Solution
finally got it working
endpoints: {
approve_user: createAuthEndpoint(
'/user_info/approve_user',
{
method: 'POST',
body: z.object({
userId: z.string()
})
},
async (ctx) => {
const updatedUser = await ctx.context.internalAdapter.updateUser(
ctx.body.userId,
{
is_approved: true
},
ctx
);
// invalidating cache
const { sessions } = await auth.api.listUserSessions({
body: {
userId: ctx.body.userId
},
headers: {
Cookie: ctx.request?.headers.get('Cookie') || ''
}
});
await Promise.allSettled(
sessions.map(async (session, i) => {
const data = await redis.get<typeof auth.$Infer.Session>(session.token);
await redis.set(session.token, JSON.stringify({ ...data, user: updatedUser }));
})
);
return ctx.json({
user: updatedUser
});
}
)
}endpoints: {
approve_user: createAuthEndpoint(
'/user_info/approve_user',
{
method: 'POST',
body: z.object({
userId: z.string()
})
},
async (ctx) => {
const updatedUser = await ctx.context.internalAdapter.updateUser(
ctx.body.userId,
{
is_approved: true
},
ctx
);
// invalidating cache
const { sessions } = await auth.api.listUserSessions({
body: {
userId: ctx.body.userId
},
headers: {
Cookie: ctx.request?.headers.get('Cookie') || ''
}
});
await Promise.allSettled(
sessions.map(async (session, i) => {
const data = await redis.get<typeof auth.$Infer.Session>(session.token);
await redis.set(session.token, JSON.stringify({ ...data, user: updatedUser }));
})
);
return ctx.json({
user: updatedUser
});
}
)
}