mirror of
https://github.com/LukeHagar/better-auth.git
synced 2025-12-09 20:27:44 +00:00
fix: refresh secondary storage sessions on user update (#4522)
This commit is contained in:
committed by
Bereket Engida
parent
809f82cb1e
commit
ccc7c48dee
@@ -386,4 +386,63 @@ describe("Email Verification Secondary Storage", async () => {
|
|||||||
expect(secondSignInSession.data?.user.email).toBe(sampleUser.email);
|
expect(secondSignInSession.data?.user.email).toBe(sampleUser.email);
|
||||||
expect(secondSignInSession.data?.user.emailVerified).toBe(true);
|
expect(secondSignInSession.data?.user.emailVerified).toBe(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("should set emailVerified on all sessions", async () => {
|
||||||
|
const sampleUser = {
|
||||||
|
name: "sampler",
|
||||||
|
email: "sample@sample.com",
|
||||||
|
password: "samplesssss",
|
||||||
|
};
|
||||||
|
|
||||||
|
await client.signUp.email({
|
||||||
|
name: sampleUser.name,
|
||||||
|
email: sampleUser.email,
|
||||||
|
password: sampleUser.password,
|
||||||
|
});
|
||||||
|
|
||||||
|
const secondSignInHeaders = new Headers();
|
||||||
|
await client.signIn.email(
|
||||||
|
{
|
||||||
|
email: sampleUser.email,
|
||||||
|
password: sampleUser.password,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
onSuccess: cookieSetter(secondSignInHeaders),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
await auth.api.sendVerificationEmail({
|
||||||
|
body: {
|
||||||
|
email: sampleUser.email,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const headers = new Headers();
|
||||||
|
await client.verifyEmail({
|
||||||
|
query: {
|
||||||
|
token,
|
||||||
|
},
|
||||||
|
fetchOptions: {
|
||||||
|
onSuccess: cookieSetter(headers),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const session = await client.getSession({
|
||||||
|
fetchOptions: {
|
||||||
|
headers,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(session.data?.user.email).toBe(sampleUser.email);
|
||||||
|
expect(session.data?.user.emailVerified).toBe(true);
|
||||||
|
|
||||||
|
const secondSignInSession = await client.getSession({
|
||||||
|
fetchOptions: {
|
||||||
|
headers: secondSignInHeaders,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(secondSignInSession.data?.user.email).toBe(sampleUser.email);
|
||||||
|
expect(secondSignInSession.data?.user.emailVerified).toBe(true);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -77,6 +77,41 @@ export const createInternalAdapter = (
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function refreshUserSessions(user: User) {
|
||||||
|
if (!secondaryStorage) return;
|
||||||
|
|
||||||
|
const listRaw = await secondaryStorage.get(`active-sessions-${user.id}`);
|
||||||
|
if (!listRaw) return;
|
||||||
|
|
||||||
|
const now = Date.now();
|
||||||
|
const list =
|
||||||
|
safeJSONParse<{ token: string; expiresAt: number }[]>(listRaw) || [];
|
||||||
|
const validSessions = list.filter((s) => s.expiresAt > now);
|
||||||
|
|
||||||
|
await Promise.all(
|
||||||
|
validSessions.map(async ({ token }) => {
|
||||||
|
const cached = await secondaryStorage.get(token);
|
||||||
|
if (!cached) return;
|
||||||
|
const parsed = safeJSONParse<{ session: Session; user: User }>(cached);
|
||||||
|
if (!parsed) return;
|
||||||
|
|
||||||
|
const sessionTTL = Math.max(
|
||||||
|
Math.floor(new Date(parsed.session.expiresAt).getTime() - now) / 1000,
|
||||||
|
0,
|
||||||
|
);
|
||||||
|
|
||||||
|
await secondaryStorage.set(
|
||||||
|
token,
|
||||||
|
JSON.stringify({
|
||||||
|
session: parsed.session,
|
||||||
|
user,
|
||||||
|
}),
|
||||||
|
sessionTTL,
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
createOAuthUser: async (
|
createOAuthUser: async (
|
||||||
user: Omit<User, "id" | "createdAt" | "updatedAt">,
|
user: Omit<User, "id" | "createdAt" | "updatedAt">,
|
||||||
|
|||||||
Reference in New Issue
Block a user