feat(login): add local users functionality (#591)

This commit is contained in:
Jakob Ankarhem
2021-01-14 13:03:12 +01:00
committed by GitHub
parent f17fa2a2db
commit 492e19df40
17 changed files with 866 additions and 97 deletions

View File

@@ -9,6 +9,12 @@ import {
} from 'typeorm';
import { Permission, hasPermission } from '../lib/permissions';
import { MediaRequest } from './MediaRequest';
import bcrypt from 'bcrypt';
import path from 'path';
import PreparedEmail from '../lib/email';
import logger from '../logger';
import { getSettings } from '../lib/settings';
import { default as generatePassword } from 'secure-random-password';
@Entity()
export class User {
@@ -16,7 +22,7 @@ export class User {
return users.map((u) => u.filter());
}
static readonly filteredFields: string[] = ['plexToken'];
static readonly filteredFields: string[] = ['plexToken', 'password'];
@PrimaryGeneratedColumn()
public id: number;
@@ -27,8 +33,14 @@ export class User {
@Column()
public username: string;
@Column({ select: false })
public plexId: number;
@Column({ nullable: true, select: false })
public password?: string;
@Column({ type: 'integer', default: 1 })
public userType = 1;
@Column({ nullable: true, select: false })
public plexId?: number;
@Column({ nullable: true, select: false })
public plexToken?: string;
@@ -69,4 +81,47 @@ export class User {
public hasPermission(permissions: Permission | Permission[]): boolean {
return !!hasPermission(permissions, this.permissions);
}
public passwordMatch(password: string): Promise<boolean> {
return new Promise((resolve, reject) => {
if (this.password) {
resolve(bcrypt.compare(password, this.password));
} else {
return reject(false);
}
});
}
public async setPassword(password: string): Promise<void> {
const hashedPassword = await bcrypt.hash(password, 12);
this.password = hashedPassword;
}
public async resetPassword(): Promise<void> {
const password = generatePassword.randomPassword({ length: 16 });
this.setPassword(password);
const applicationUrl = getSettings().main.applicationUrl;
try {
logger.info(`Sending password email for ${this.email}`, {
label: 'User creation',
});
const email = new PreparedEmail();
await email.send({
template: path.join(__dirname, '../templates/email/password'),
message: {
to: this.email,
},
locals: {
password: password,
applicationUrl,
},
});
} catch (e) {
logger.error('Failed to send out password email', {
label: 'User creation',
message: e.message,
});
}
}
}