UNPKG

@wepublish/api-db-mongodb

Version:

We.publish Database adapter for mongoDB

164 lines (137 loc) 4.3 kB
import { OptionalUserSession, OptionalSession, User, SessionType, UserSession, DBSessionAdapter } from '@wepublish/api' import {Collection, Db} from 'mongodb' import {CollectionName, DBSession, DBToken} from './schema' import {generateToken} from '../utility' import {MongoDBUserAdapter} from './user' import {MongoDBUserRoleAdapter} from './userRole' export class MongoDBSessionAdapter implements DBSessionAdapter { private sessions: Collection<DBSession> private tokens: Collection<DBToken> private user: MongoDBUserAdapter private userRole: MongoDBUserRoleAdapter private sessionTTL: number constructor( db: Db, user: MongoDBUserAdapter, userRole: MongoDBUserRoleAdapter, sessionTTL: number ) { this.sessions = db.collection(CollectionName.Sessions) this.tokens = db.collection(CollectionName.Tokens) this.user = user this.userRole = userRole this.sessionTTL = sessionTTL } async createUserSession(user: User): Promise<OptionalUserSession> { const token = generateToken() const createdAt = new Date() const expiresAt = new Date(Date.now() + this.sessionTTL) const {insertedId: id} = await this.sessions.insertOne({ token: token, userID: user.id, createdAt, expiresAt }) return { type: SessionType.User, id, user, token, createdAt, expiresAt, roles: await this.userRole.getNonOptionalUserRolesByID(user.roleIDs) } } async deleteUserSessionByToken(token: string): Promise<boolean> { const {deletedCount} = await this.sessions.deleteOne({token}) return deletedCount === 1 } async getSessionByToken(token: string): Promise<OptionalSession> { const [tokenMatch, session] = await Promise.all([ this.tokens.findOne({token}), this.sessions.findOne({token}) ]) if (tokenMatch) { return { type: SessionType.Token, id: tokenMatch._id, name: tokenMatch.name, token: tokenMatch.token, roles: await this.userRole.getNonOptionalUserRolesByID(tokenMatch.roleIDs) } } else if (session) { const user = await this.user.getUserByID(session.userID) if (!user) return null return { type: SessionType.User, id: session._id, token: session.token, createdAt: session.createdAt, expiresAt: session.expiresAt, user, roles: await this.userRole.getNonOptionalUserRolesByID(user.roleIDs) } } return null } async extendUserSessionByToken(token: string): Promise<OptionalUserSession> { const {value} = await this.sessions.findOneAndUpdate( {token}, { $set: { expiresAt: new Date(Date.now() + this.sessionTTL) } }, {returnOriginal: false} ) if (!value) return null const user = await this.user.getUserByID(value.userID) if (!user) return null return { type: SessionType.User, id: value._id, token: value.token, createdAt: value.createdAt, expiresAt: value.expiresAt, user, roles: await this.userRole.getNonOptionalUserRolesByID(user.roleIDs) } } async deleteUserSessionByID(user: User, id: string): Promise<boolean> { const {deletedCount} = await this.sessions.deleteOne({_id: id, userID: user.id}) return deletedCount === 1 } async getUserSessions(user: User): Promise<UserSession[]> { const sessions = await this.sessions.find({userID: user.id}).toArray() const roles = await this.userRole.getNonOptionalUserRolesByID(user.roleIDs) return sessions.map(session => ({ type: SessionType.User, id: session._id, token: session.token, createdAt: session.createdAt, expiresAt: session.expiresAt, user, roles })) } async getSessionByID(user: User, id: string): Promise<OptionalSession> { const session = await this.sessions.findOne({_id: id, userID: user.id}) if (!session) return null return { type: SessionType.User, id: session._id, token: session.token, createdAt: session.createdAt, expiresAt: session.expiresAt, user: user, roles: await this.userRole.getNonOptionalUserRolesByID(user.roleIDs) } } }