UNPKG

@accounts/mikro-orm

Version:
286 lines 10.6 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.AccountsMikroOrm = void 0; const tslib_1 = require("tslib"); const User_1 = require("./entity/User"); const Email_1 = require("./entity/Email"); const Service_1 = require("./entity/Service"); const Session_1 = require("./entity/Session"); const types_1 = require("./types"); const core_1 = require("@mikro-orm/core"); const graphql_modules_1 = require("graphql-modules"); const lodash_1 = require("lodash"); const hasPassword = (opt) => !!opt.bcrypt; const toUser = async (user) => user && { ...user, id: String(user.id), emails: await user.emails.loadItems(), services: (await user.services.loadItems()).reduce((acc, { name, token, options }) => { const multi = ['email.verificationTokens', 'password.reset']; (0, lodash_1.set)(acc, name, multi.includes(name) ? ((0, lodash_1.get)(acc, name) ?? []).concat({ token, ...options }) : { ...(0, lodash_1.get)(acc, name), token, ...options }); return acc; }, {}), }; const toSession = async (session) => session && { ...session, id: String(session.id), userId: String(session.user.id), //FIXME createdAt: session.createdAt.toDateString(), updatedAt: session.updatedAt.toDateString(), }; let AccountsMikroOrm = class AccountsMikroOrm { context; get em() { const em = core_1.RequestContext.getEntityManager() ?? this.context?.em ?? this.context?.injector.get(core_1.EntityManager); if (!em) { throw new Error('Cannot find EntityManager'); } return em; } UserEntity; EmailEntity = Email_1.Email; ServiceEntity = Service_1.Service; SessionEntity = Session_1.Session; get userRepository() { return this.em.getRepository(this.UserEntity); } get emailRepository() { return this.em.getRepository(this.EmailEntity); } get serviceRepository() { return this.em.getRepository(this.ServiceEntity); } get sessionRepository() { return this.em.getRepository(this.SessionEntity); } constructor(EmailEntity, ServiceEntity, SessionEntity, UserEntity) { if (EmailEntity) { this.EmailEntity = EmailEntity; } if (ServiceEntity) { this.ServiceEntity = ServiceEntity; } if (SessionEntity) { this.SessionEntity = SessionEntity; } this.UserEntity = (0, User_1.getUserCtor)({ EmailEntity: this.EmailEntity, ServiceEntity: this.ServiceEntity, }); if (UserEntity) { this.UserEntity = UserEntity; } } async findUserByEmail(email) { return toUser(await this.userRepository.findOne({ emails: { address: email.toLocaleLowerCase(), }, })); } async findUserByUsername(username) { return toUser(await this.userRepository.findOne({ username })); } async findUserById(userId) { return toUser(await this.userRepository.findOne(Number(userId))); } async findUserByResetPasswordToken(token) { return toUser(await this.userRepository.findOne({ services: { name: 'password.reset', token, }, })); } async findUserByEmailVerificationToken(token) { return toUser(await this.userRepository.findOne({ services: { name: 'email.verificationTokens', token, }, })); } async createUser({ username, email, password, ...otherFields }) { const user = new this.UserEntity({ email, password, username, ...otherFields, }); await this.em.persistAndFlush(user); return String(user.id); } async setUsername(userId, newUsername) { const user = await this.userRepository.findOneOrFail(Number(userId)); user.username = newUsername; await this.em.flush(); } async findUserByServiceId(serviceName, serviceId) { return toUser(await this.userRepository.findOne({ services: Number(serviceId) })); } async setService(userId, serviceName, data, token, flush = true) { const service = (await this.serviceRepository.findOne({ name: serviceName, user: Number(userId), })) ?? new this.ServiceEntity({ name: serviceName, user: this.em.getReference(this.UserEntity, Number(userId), { wrapped: true }), }); // eslint-disable-next-line @typescript-eslint/no-unused-vars const { id, ...options } = data; service.options = options; if (token) { service.token = token; } this.em.persist(service); if (flush) { return this.em.flush(); } } async unsetService(userId, serviceName) { this.em.remove(await this.serviceRepository.findOneOrFail({ name: serviceName, user: Number(userId), })); return this.em.flush(); } async findPasswordHash(userId) { const service = await this.serviceRepository.findOne({ name: 'password', user: Number(userId), }); return service?.options && hasPassword(service.options) ? service.options.bcrypt : null; } async setPassword(userId, newPassword, flush = true) { return await this.setService(userId, 'password', { bcrypt: newPassword }, undefined, flush); } async addResetPasswordToken(userId, email, token, reason) { await this.setService(userId, 'password.reset', { address: email.toLocaleLowerCase(), when: new Date().toJSON(), reason, }, token); } async setResetPassword(userId, email, newPassword) { await this.setPassword(userId, newPassword, false); return this.unsetService(userId, 'password.reset'); } async addEmail(userId, newEmail, verified) { return this.em.persistAndFlush(new this.EmailEntity({ user: this.em.getReference(this.UserEntity, Number(userId), { wrapped: true }), address: newEmail, verified, })); } async removeEmail(userId, email) { try { this.em.remove(await this.emailRepository.findOneOrFail({ address: email.toLocaleLowerCase(), })); } catch { throw new Error('Email not found'); } return this.em.flush(); } async verifyEmail(userId, email) { const userEmail = await this.emailRepository.findOneOrFail({ address: email.toLocaleLowerCase(), }); userEmail.verified = true; return this.unsetService(userId, 'email.verificationTokens'); } async addEmailVerificationToken(userId, email, token) { await this.setService(userId, 'email.verificationTokens', { address: email.toLocaleLowerCase(), when: new Date(), }, token); } async removeAllResetPasswordTokens(userId) { await this.unsetService(userId, 'password.reset'); } async setUserDeactivated(userId, deactivated) { const user = await this.userRepository.findOneOrFail(Number(userId)); user.deactivated = deactivated; return this.em.flush(); } async findSessionById(sessionId) { return toSession(await this.sessionRepository.findOne(Number(sessionId))); } async findSessionByToken(token) { return toSession(await this.sessionRepository.findOne({ token })); } async findUserByLoginToken(token) { const service = await this.serviceRepository.findOne({ name: 'magicLink.loginTokens', token, }); if (service) { return this.findUserById(service.user.id); //FIXME } return null; } async addLoginToken(userId, email, token) { await this.setService(userId, 'magicLink.loginTokens', { address: email.toLocaleLowerCase(), when: new Date().toJSON(), }, token); } async removeAllLoginTokens(userId) { await this.unsetService(userId, 'magicLink.loginTokens'); } async createSession(userId, token, connection = {}, extra) { const session = new this.SessionEntity({ user: this.em.getReference(this.UserEntity, Number(userId), { wrapped: true }), token, userAgent: connection.userAgent, ip: connection.ip, extra, valid: true, }); await this.em.persistAndFlush(session); return String(session.id); } async updateSession(sessionId, connection) { const session = await this.sessionRepository.findOneOrFail(Number(sessionId)); session.userAgent = connection.userAgent ?? undefined; session.ip = connection.ip ?? undefined; return this.em.flush(); } async invalidateSession(sessionId) { const session = await this.sessionRepository.findOneOrFail(Number(sessionId)); session.valid = false; return this.em.flush(); } async invalidateAllSessions(userId, excludedSessionIds) { const sessions = await this.sessionRepository.find({ user: this.em.getReference(this.UserEntity, Number(userId), { wrapped: true }), ...(excludedSessionIds?.length && { id: { $nin: excludedSessionIds.map((id) => Number(id)) }, }), }); sessions.forEach((session) => (session.valid = false)); return this.em.flush(); } }; exports.AccountsMikroOrm = AccountsMikroOrm; tslib_1.__decorate([ (0, graphql_modules_1.ExecutionContext)(), tslib_1.__metadata("design:type", Object) ], AccountsMikroOrm.prototype, "context", void 0); exports.AccountsMikroOrm = AccountsMikroOrm = tslib_1.__decorate([ (0, graphql_modules_1.Injectable)({ global: true, }), tslib_1.__param(0, (0, graphql_modules_1.Inject)(types_1.EmailToken)), tslib_1.__param(1, (0, graphql_modules_1.Inject)(types_1.ServiceToken)), tslib_1.__param(2, (0, graphql_modules_1.Inject)(types_1.SessionToken)), tslib_1.__param(3, (0, graphql_modules_1.Inject)(types_1.UserToken)), tslib_1.__metadata("design:paramtypes", [Object, Object, Object, Object]) ], AccountsMikroOrm); //# sourceMappingURL=mikro-orm.js.map