UNPKG

@auth/pg-adapter

Version:

Postgres adapter for next-auth.

221 lines (220 loc) 7.72 kB
/** * <div style={{display: "flex", justifyContent: "space-between", alignItems: "center", padding: 16}}> * <p>An official <a href="https://www.postgresql.org/">PostgreSQL</a> adapter for Auth.js / NextAuth.js.</p> * <a href="https://www.postgresql.org/"> * <img style={{display: "block"}} src="/img/adapters/pg.svg" width="48" /> * </a> * </div> * * ## Installation * * ```bash npm2yarn * npm install next-auth @auth/pg-adapter pg * ``` * * @module @auth/pg-adapter */ export function mapExpiresAt(account) { const expires_at = parseInt(account.expires_at); return { ...account, expires_at, }; } export default function PostgresAdapter(client) { return { async createVerificationToken(verificationToken) { const { identifier, expires, token } = verificationToken; const sql = ` INSERT INTO verification_token ( identifier, expires, token ) VALUES ($1, $2, $3) `; await client.query(sql, [identifier, expires, token]); return verificationToken; }, async useVerificationToken({ identifier, token, }) { const sql = `delete from verification_token where identifier = $1 and token = $2 RETURNING identifier, expires, token `; const result = await client.query(sql, [identifier, token]); return result.rowCount !== 0 ? result.rows[0] : null; }, async createUser(user) { const { name, email, emailVerified, image } = user; const sql = ` INSERT INTO users (name, email, "emailVerified", image) VALUES ($1, $2, $3, $4) RETURNING id, name, email, "emailVerified", image`; const result = await client.query(sql, [ name, email, emailVerified, image, ]); return result.rows[0]; }, async getUser(id) { const sql = `select * from users where id = $1`; try { const result = await client.query(sql, [id]); return result.rowCount === 0 ? null : result.rows[0]; } catch { return null; } }, async getUserByEmail(email) { const sql = `select * from users where email = $1`; const result = await client.query(sql, [email]); return result.rowCount !== 0 ? result.rows[0] : null; }, async getUserByAccount({ providerAccountId, provider, }) { const sql = ` select u.* from users u join accounts a on u.id = a."userId" where a.provider = $1 and a."providerAccountId" = $2`; const result = await client.query(sql, [provider, providerAccountId]); return result.rowCount !== 0 ? result.rows[0] : null; }, async updateUser(user) { const fetchSql = `select * from users where id = $1`; const query1 = await client.query(fetchSql, [user.id]); const oldUser = query1.rows[0]; const newUser = { ...oldUser, ...user, }; const { id, name, email, emailVerified, image } = newUser; const updateSql = ` UPDATE users set name = $2, email = $3, "emailVerified" = $4, image = $5 where id = $1 RETURNING name, id, email, "emailVerified", image `; const query2 = await client.query(updateSql, [ id, name, email, emailVerified, image, ]); return query2.rows[0]; }, async linkAccount(account) { const sql = ` insert into accounts ( "userId", provider, type, "providerAccountId", access_token, expires_at, refresh_token, id_token, scope, session_state, token_type ) values ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11) returning id, "userId", provider, type, "providerAccountId", access_token, expires_at, refresh_token, id_token, scope, session_state, token_type `; const params = [ account.userId, account.provider, account.type, account.providerAccountId, account.access_token, account.expires_at, account.refresh_token, account.id_token, account.scope, account.session_state, account.token_type, ]; const result = await client.query(sql, params); return mapExpiresAt(result.rows[0]); }, async createSession({ sessionToken, userId, expires }) { if (userId === undefined) { throw Error(`userId is undef in createSession`); } const sql = `insert into sessions ("userId", expires, "sessionToken") values ($1, $2, $3) RETURNING id, "sessionToken", "userId", expires`; const result = await client.query(sql, [userId, expires, sessionToken]); return result.rows[0]; }, async getSessionAndUser(sessionToken) { if (sessionToken === undefined) { return null; } const result1 = await client.query(`select * from sessions where "sessionToken" = $1`, [sessionToken]); if (result1.rowCount === 0) { return null; } const session = result1.rows[0]; const result2 = await client.query("select * from users where id = $1", [ session.userId, ]); if (result2.rowCount === 0) { return null; } const user = result2.rows[0]; return { session, user, }; }, async updateSession(session) { const { sessionToken } = session; const result1 = await client.query(`select * from sessions where "sessionToken" = $1`, [sessionToken]); if (result1.rowCount === 0) { return null; } const originalSession = result1.rows[0]; const newSession = { ...originalSession, ...session, }; const sql = ` UPDATE sessions set expires = $2 where "sessionToken" = $1 `; const result = await client.query(sql, [ newSession.sessionToken, newSession.expires, ]); return result.rows[0]; }, async deleteSession(sessionToken) { const sql = `delete from sessions where "sessionToken" = $1`; await client.query(sql, [sessionToken]); }, async unlinkAccount(partialAccount) { const { provider, providerAccountId } = partialAccount; const sql = `delete from accounts where "providerAccountId" = $1 and provider = $2`; await client.query(sql, [providerAccountId, provider]); }, async deleteUser(userId) { await client.query(`delete from users where id = $1`, [userId]); await client.query(`delete from sessions where "userId" = $1`, [userId]); await client.query(`delete from accounts where "userId" = $1`, [userId]); }, }; }