Switched emails to being mandetory for users

ref #93
This commit is contained in:
Nicolai Ort 2021-01-13 17:44:22 +01:00
parent cf788fe07b
commit 9feeb302e8
8 changed files with 40 additions and 24 deletions

View File

@ -4,7 +4,7 @@ import { NotAcceptableError, NotFoundError } from 'routing-controllers';
/** /**
* Error to throw when no username or email is set. * Error to throw when no username or email is set.
* We somehow need to identify you :) * We somehow need to identify you on login.
*/ */
export class UsernameOrEmailNeededError extends NotFoundError { export class UsernameOrEmailNeededError extends NotFoundError {
@IsString() @IsString()
@ -14,6 +14,18 @@ export class UsernameOrEmailNeededError extends NotFoundError {
message = "No username or email is set!" message = "No username or email is set!"
} }
/**
* Error to throw when no email is set.
* We somehow need to identify you :)
*/
export class UserEmailNeededError extends NotFoundError {
@IsString()
name = "UserEmailNeededError"
@IsString()
message = "No email is set! \n You have to provide email addresses for users (used for password reset among others)."
}
/** /**
* Error to throw when a user couldn't be found. * Error to throw when a user couldn't be found.
*/ */

View File

@ -1,9 +1,9 @@
import * as argon2 from "argon2"; import * as argon2 from "argon2";
import { IsBoolean, IsEmail, IsOptional, IsPhoneNumber, IsString, IsUrl } from 'class-validator'; import { IsBoolean, IsEmail, IsNotEmpty, IsOptional, IsPhoneNumber, IsString, IsUrl } from 'class-validator';
import { getConnectionManager } from 'typeorm'; import { getConnectionManager } from 'typeorm';
import * as uuid from 'uuid'; import * as uuid from 'uuid';
import { config } from '../../../config'; import { config } from '../../../config';
import { UsernameOrEmailNeededError } from '../../../errors/UserErrors'; import { UserEmailNeededError } from '../../../errors/UserErrors';
import { UserGroupNotFoundError } from '../../../errors/UserGroupErrors'; import { UserGroupNotFoundError } from '../../../errors/UserGroupErrors';
import { User } from '../../entities/User'; import { User } from '../../entities/User';
import { UserGroup } from '../../entities/UserGroup'; import { UserGroup } from '../../entities/UserGroup';
@ -33,7 +33,7 @@ export class CreateUser {
/** /**
* The new user's username. * The new user's username.
* You have to provide at least one of: {email, username}. * You have to provide a email addres, so this is optional.
*/ */
@IsOptional() @IsOptional()
@IsString() @IsString()
@ -41,12 +41,11 @@ export class CreateUser {
/** /**
* The new user's email address. * The new user's email address.
* You have to provide at least one of: {email, username}.
*/ */
@IsEmail() @IsEmail()
@IsString() @IsString()
@IsOptional() @IsNotEmpty()
email?: string; email: string;
/** /**
* The new user's phone number. * The new user's phone number.
@ -92,8 +91,8 @@ export class CreateUser {
public async toEntity(): Promise<User> { public async toEntity(): Promise<User> {
let newUser: User = new User(); let newUser: User = new User();
if (this.email === undefined && this.username === undefined) { if (!this.email) {
throw new UsernameOrEmailNeededError(); throw new UserEmailNeededError();
} }
newUser.email = this.email newUser.email = this.email

View File

@ -1,8 +1,8 @@
import * as argon2 from "argon2"; import * as argon2 from "argon2";
import { IsBoolean, IsEmail, IsInt, IsOptional, IsPhoneNumber, IsString, IsUrl } from 'class-validator'; import { IsBoolean, IsEmail, IsInt, IsNotEmpty, IsOptional, IsPhoneNumber, IsString, IsUrl } from 'class-validator';
import { getConnectionManager } from 'typeorm'; import { getConnectionManager } from 'typeorm';
import { config } from '../../../config'; import { config } from '../../../config';
import { UsernameOrEmailNeededError } from '../../../errors/AuthError'; import { UserEmailNeededError } from '../../../errors/UserErrors';
import { UserGroupNotFoundError } from '../../../errors/UserGroupErrors'; import { UserGroupNotFoundError } from '../../../errors/UserGroupErrors';
import { User } from '../../entities/User'; import { User } from '../../entities/User';
import { UserGroup } from '../../entities/UserGroup'; import { UserGroup } from '../../entities/UserGroup';
@ -40,7 +40,7 @@ export class UpdateUser {
/** /**
* The updated user's username. * The updated user's username.
* You have to provide at least one of: {email, username}. * You have to provide a email addres, so this is optional.
*/ */
@IsOptional() @IsOptional()
@IsString() @IsString()
@ -48,12 +48,11 @@ export class UpdateUser {
/** /**
* The updated user's email address. * The updated user's email address.
* You have to provide at least one of: {email, username}.
*/ */
@IsEmail() @IsEmail()
@IsString() @IsString()
@IsOptional() @IsNotEmpty()
email?: string; email: string;
/** /**
* The updated user's phone number. * The updated user's phone number.
@ -99,11 +98,11 @@ export class UpdateUser {
* @param user The user that shall be updated. * @param user The user that shall be updated.
*/ */
public async update(user: User): Promise<User> { public async update(user: User): Promise<User> {
if (!this.email) {
throw new UserEmailNeededError();
}
user.email = this.email; user.email = this.email;
user.username = this.username; user.username = this.username;
if ((user.email === undefined || user.email === null) && (user.username === undefined || user.username === null)) {
throw new UsernameOrEmailNeededError();
}
if (this.password) { if (this.password) {
user.password = await argon2.hash(this.password + user.uuid); user.password = await argon2.hash(this.password + user.uuid);
user.refreshTokenCount = user.refreshTokenCount + 1; user.refreshTokenCount = user.refreshTokenCount + 1;

View File

@ -25,9 +25,10 @@ export class User extends Principal {
* The user's e-mail address. * The user's e-mail address.
* Either username or email has to be set (otherwise the user couldn't log in). * Either username or email has to be set (otherwise the user couldn't log in).
*/ */
@Column({ nullable: true, unique: true }) @Column({ nullable: false, unique: true })
@IsEmail() @IsEmail()
email?: string; @IsNotEmpty()
email: string;
/** /**
* The user's phone number. * The user's phone number.

View File

@ -33,6 +33,7 @@ export default class SeedUsers implements Seeder {
initialUser.lastname = "demo"; initialUser.lastname = "demo";
initialUser.username = "demo"; initialUser.username = "demo";
initialUser.password = "demo"; initialUser.password = "demo";
initialUser.email = "demo@dev.lauf-fuer-kaya.de"
initialUser.groups = group; initialUser.groups = group;
return await connection.getRepository(User).save(await initialUser.toEntity()); return await connection.getRepository(User).save(await initialUser.toEntity());
} }

View File

@ -14,7 +14,8 @@ beforeAll(async () => {
"middlename": "demo_logout", "middlename": "demo_logout",
"lastname": "demo_logout", "lastname": "demo_logout",
"username": "demo_logout", "username": "demo_logout",
"password": "demo_logout" "password": "demo_logout",
"email": "demo_logout@dev.lauf-fuer-kaya.de"
}, { }, {
headers: { "authorization": "Bearer " + res_login.data["access_token"] }, headers: { "authorization": "Bearer " + res_login.data["access_token"] },
validateStatus: undefined validateStatus: undefined

View File

@ -14,7 +14,8 @@ beforeAll(async () => {
"middlename": "demo_refresh", "middlename": "demo_refresh",
"lastname": "demo_refresh", "lastname": "demo_refresh",
"username": "demo_refresh", "username": "demo_refresh",
"password": "demo_refresh" "password": "demo_refresh",
"email": "demo_refresh@dev.lauf-fuer-kaya.de"
}, { }, {
headers: { "authorization": "Bearer " + res_login.data["access_token"] }, headers: { "authorization": "Bearer " + res_login.data["access_token"] },
validateStatus: undefined validateStatus: undefined

View File

@ -14,7 +14,8 @@ beforeAll(async () => {
"middlename": "demo_reset", "middlename": "demo_reset",
"lastname": "demo_reset", "lastname": "demo_reset",
"username": "demo_reset", "username": "demo_reset",
"password": "demo_reset" "password": "demo_reset",
"email": "demo_reset@dev.lauf-fuer-kaya.de"
}, { }, {
headers: { "authorization": "Bearer " + res_login.data["access_token"] }, headers: { "authorization": "Bearer " + res_login.data["access_token"] },
validateStatus: undefined validateStatus: undefined
@ -24,7 +25,8 @@ beforeAll(async () => {
"middlename": "demo_reset2", "middlename": "demo_reset2",
"lastname": "demo_reset2", "lastname": "demo_reset2",
"username": "demo_reset2", "username": "demo_reset2",
"password": "demo_reset2" "password": "demo_reset2",
"email": "demo_reset1@dev.lauf-fuer-kaya.de"
}, { }, {
headers: { "authorization": "Bearer " + res_login.data["access_token"] }, headers: { "authorization": "Bearer " + res_login.data["access_token"] },
validateStatus: undefined validateStatus: undefined