Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import { ConnectionInformations, CreateUser, DatabaseInterface, Session } from '@accounts/types';
- import { Repository, getRepository } from 'typeorm';
- import { User } from '../entity/User';
- import { UserEmail } from '../entity/UserEmail';
- import { UserService } from '../entity/UserService';
- import { UserSession } from '../entity/UserSession';
- type ISession = Session & UserSession;
- export class Typeorm implements DatabaseInterface {
- private userRepository: Repository<User>;
- private serviceRepository: Repository<UserService>;
- private emailRepository: Repository<UserEmail>;
- private sessionRepository: Repository<UserSession>;
- constructor() {
- this.userRepository = getRepository(User);
- this.serviceRepository = getRepository(UserService);
- this.emailRepository = getRepository(UserEmail);
- this.sessionRepository = getRepository(UserSession);
- }
- public async findUserByEmail(email: string): Promise<User | null> {
- return this.userRepository.findOne({
- where: { email },
- });
- }
- public async findUserByUsername(username: string): Promise<User | null> {
- return this.userRepository.findOne({
- where: { username },
- });
- }
- public async findUserById(userId: string): Promise<User | null> {
- const user = await this.userRepository.findOne(userId);
- if (!user) {
- throw new Error('User not found');
- }
- return user;
- }
- public async findUserByResetPasswordToken(token: string): Promise<User | null> {
- const service = await this.serviceRepository.findOne({
- where: {
- name: 'password.reset',
- token,
- },
- });
- return service.user;
- }
- public async findUserByEmailVerificationToken(token: string): Promise<User | null> {
- const service = await this.serviceRepository.findOne({
- where: {
- name: 'email.verification',
- token,
- },
- });
- return service.user;
- }
- public async createUser(createUser: CreateUser): Promise<string> {
- const { username, email, password } = createUser;
- const user = new User();
- if (email) {
- const userEmail = new UserEmail();
- userEmail.address = email;
- userEmail.verified = false;
- this.emailRepository.save(userEmail);
- user.emails = [userEmail];
- }
- if (password) {
- const userService = new UserService();
- userService.name = 'password';
- userService.options = { bcrypt: password };
- await this.serviceRepository.save(userService);
- user.services = [userService];
- }
- if (username) {
- user.username = username;
- }
- await this.userRepository.save(user);
- return user.id;
- }
- public async setUsername(userId: string, newUsername: string): Promise<void> {
- const user = await this.findUserById(userId);
- user.username = newUsername;
- await this.userRepository.save(user);
- }
- public async setProfile(userId: string, profile: object): Promise<object> {
- const user = await this.findUserById(userId);
- user.profile = profile;
- await this.userRepository.save(user);
- return profile;
- }
- public async findUserByServiceId(serviceName: string, serviceId: string): Promise<User | null> {
- const service = await this.serviceRepository.findOne({
- name: serviceName,
- id: serviceId,
- });
- if (service) {
- return service.user;
- }
- }
- public async setService(userId: string, serviceName: string, data: object): Promise<void> {
- const user = await this.findUserById(userId);
- const service = user.services.find((s) => s.name === serviceName);
- if (service) {
- service.options = data;
- await this.serviceRepository.save(service); // @todo is this needed?
- await this.userRepository.save(user);
- }
- }
- public async unsetService(userId: string, serviceName: string): Promise<void> {
- const user = await this.findUserById(userId);
- const service = user.services && user.services.find((s) => s.name === serviceName);
- if (service) {
- await this.serviceRepository.remove(service);
- await this.userRepository.save(user);
- }
- }
- public async findPasswordHash(userId: string): Promise<string | null> {
- const user = await this.findUserById(userId);
- const service = user.services && user.services.find((s) => s.name === 'password');
- return service.options && service.options.bcrypt;
- return null;
- }
- public async setPassword(userId: string, newPassword: string): Promise<void> {
- const user = await this.findUserById(userId);
- const service = user.services && user.services.find((s) => s.name === 'password');
- service.options = { bcrypt: newPassword };
- await this.serviceRepository.save(service);
- await this.userRepository.save(user);
- }
- public async addResetPasswordToken(userId: string, email: string, token: string, reason: string): Promise<void> {
- const user = await this.findUserById(userId);
- const service = new UserService();
- service.name = 'password.reset';
- service.token = token;
- service.options = {
- email: email.toLocaleLowerCase(),
- when: (new Date()).toJSON(),
- reason,
- };
- await this.serviceRepository.save(service);
- user.services.push(service);
- await this.userRepository.save(user);
- }
- public async setResetPassword(userId: string, email: string, newPassword: string, token: string): Promise<void> {
- await this.setPassword(userId, newPassword);
- }
- public async addEmail(userId: string, newEmail: string, verified: boolean): Promise<void> {
- const user = await this.findUserById(userId);
- const userEmail = new UserEmail();
- userEmail.address = newEmail;
- userEmail.verified = verified;
- user.emails.push(userEmail);
- await this.userRepository.save(user);
- }
- public async removeEmail(userId: string, email: string): Promise<void> {
- const user = await this.findUserById(userId);
- const userEmail = user.emails.find((s) => s.address === email);
- if (!userEmail) {
- throw new Error('Email not found');
- }
- await this.emailRepository.remove(userEmail);
- }
- public async verifyEmail(userId: string, email: string): Promise<void> {
- const user = await this.findUserById(userId);
- const userEmail = user.emails.find((s) => s.address === email);
- if (!userEmail) {
- throw new Error('Email not found');
- }
- userEmail.verified = true;
- await this.emailRepository.save(userEmail);
- }
- public async addEmailVerificationToken(userId: string, email: string, token: string): Promise<void> {
- const user = await this.findUserById(userId);
- const service = new UserService();
- service.token = token;
- service.name = 'email.verification';
- await this.serviceRepository.save(service);
- user.services.push(service);
- await this.userRepository.save(user);
- }
- public async setUserDeactivated(userId: string, deactivated: boolean): Promise<void> {
- const user = await this.findUserById(userId);
- user.deactivated = deactivated;
- await this.userRepository.save(user);
- }
- public findSessionById(sessionId: string): Promise<Session | null> {
- return this.sessionRepository.findOne(sessionId) as Promise<ISession>;
- }
- public findSessionByToken(token: string): Promise<ISession | null> {
- return this.sessionRepository.findOne({ token }) as Promise<ISession>;
- }
- public async createSession(
- userId: string,
- token: string,
- connection: ConnectionInformations,
- extra?: object,
- ): Promise<string> {
- const user = await this.findUserById(userId);
- const session = new UserSession();
- session.token = token;
- session.userAgent = connection.userAgent;
- session.ip = connection.ip;
- session.extra = extra;
- session.valid = true;
- await this.sessionRepository.save(session);
- user.sessions.push(session);
- await this.userRepository.save(user);
- return session.id;
- }
- public async updateSession(sessionId: string, connection: ConnectionInformations): Promise<void> {
- const session = await this.findSessionById(sessionId);
- session.userAgent = connection.userAgent;
- session.ip = connection.ip;
- await this.sessionRepository.save(session);
- }
- public async invalidateSession(sessionId: string): Promise<void> {
- const session = await this.findSessionById(sessionId);
- session.valid = false;
- await this.sessionRepository.save(session);
- }
- public async invalidateAllSessions(userId: string): Promise<void> {
- const user = await this.findUserById(userId);
- await Promise.all(
- user.sessions.map((session) =>
- this.sessionRepository.delete(session),
- ),
- );
- }
- }
Add Comment
Please, Sign In to add comment