metamigo: do nextauth v3 -> v4 upgrades

This commit is contained in:
Abel Luck 2023-06-06 10:28:29 +00:00
parent a33f80c497
commit 45f8cb1234
13 changed files with 158 additions and 123 deletions

View file

@ -1,10 +1,16 @@
/* eslint-disable unicorn/no-null,max-params */
import { createHash, randomBytes } from "node:crypto";
import omit from "lodash/omit.js";
import type { IMetamigoRepositories } from "../records/index.js";
import { IMetamigoRepositories, idKeysOf } from "../records/index.js";
import type { UnsavedAccount } from "../records/account.js";
import type { UserId, UnsavedUser, SavedUser } from "../records/user.js";
import type { UnsavedSession, SavedSession } from "../records/session.js";
import {
AdapterAccount,
AdapterSession,
AdapterUser,
} from "next-auth/adapters.js";
import { ReadableStreamDefaultController } from "stream/web";
// Sessions expire after 30 days of being idle
export const defaultSessionMaxAge = 30 * 24 * 60 * 60 * 1000;
@ -23,7 +29,7 @@ export class NextAuthAdapter<TRepositories extends IMetamigoRepositories> {
private repos: TRepositories,
private readonly sessionMaxAge = defaultSessionMaxAge,
private readonly sessionUpdateAge = defaulteSessionUpdateAge
) { }
) {}
async createUser(profile: UnsavedUser): Promise<SavedUser> {
// @ts-expect-error Typescript doesn't like lodash's omit()
@ -56,12 +62,12 @@ export class NextAuthAdapter<TRepositories extends IMetamigoRepositories> {
return user;
}
async getUserByProviderAccountId(
providerId: string,
async getUserByAccount(
provider: string,
providerAccountId: string
): Promise<SavedUser | null> {
const account = await this.repos.accounts.findBy({
compoundId: getCompoundId(providerId, providerAccountId),
compoundId: getCompoundId(provider, providerAccountId),
});
if (!account) return null;
@ -72,15 +78,16 @@ export class NextAuthAdapter<TRepositories extends IMetamigoRepositories> {
return this.repos.users.update(user);
}
async linkAccount(
userId: string,
providerId: string,
providerType: string,
providerAccountId: string,
refreshToken: string,
accessToken: string,
accessTokenExpires: number
): Promise<void> {
async linkAccount(adapterAccount: AdapterAccount): Promise<void> {
const {
userId,
access_token: accessToken,
refresh_token: refreshToken,
provider: providerId,
providerAccountId,
expires_at: accessTokenExpires,
type: providerType,
} = adapterAccount;
const exists = await this.repos.users.existsById({ id: userId });
if (!exists) return;
const account: UnsavedAccount = {
@ -109,7 +116,13 @@ export class NextAuthAdapter<TRepositories extends IMetamigoRepositories> {
});
}
createSession(user: SavedUser): Promise<SavedSession> {
createSession({
sessionToken,
userId,
}: {
sessionToken: string;
userId: string;
}): Promise<SavedSession> {
let expires;
if (this.sessionMaxAge) {
const dateExpires = new Date(Date.now() + this.sessionMaxAge);
@ -118,22 +131,41 @@ export class NextAuthAdapter<TRepositories extends IMetamigoRepositories> {
const session: UnsavedSession = {
expires,
userId: user.id,
sessionToken: randomToken(),
userId,
sessionToken,
//sessionToken: randomToken(),
accessToken: randomToken(),
};
return this.repos.sessions.insert(session);
}
async getSession(sessionToken: string): Promise<SavedSession | null> {
async getSessionAndUser(
sessionToken: string
): Promise<{ session: AdapterSession; user: AdapterUser } | null> {
const session = await this.repos.sessions.findBy({ sessionToken });
if (!session) return null;
if (session && session.expires && new Date() > session.expires) {
this.repos.sessions.remove(session);
return null;
}
return session;
const user = await this.repos.users.findById({ id: session.userId });
if (!user) return null;
const adapterSession: AdapterSession = {
userId: session.userId,
expires: session.expires,
sessionToken: sessionToken,
};
const adapterUser: AdapterUser = {
id: user.id,
email: user.email,
emailVerified: user.emailVerified,
};
return { session: adapterSession, user: adapterUser };
}
async updateSession(