Fix toolbar and reformat backend code

This commit is contained in:
Norbi Peti 2022-03-03 00:08:40 +01:00
parent 30433e5985
commit 2a7aa2a65a
No known key found for this signature in database
GPG key ID: DBA4C4549A927E56
18 changed files with 729 additions and 728 deletions

View file

@ -1,110 +1,111 @@
import { import {
Count, Count,
CountSchema, CountSchema,
Filter, Filter,
repository, repository,
Where, Where,
} from '@loopback/repository'; } from '@loopback/repository';
import { import {
del, del,
get, get,
getModelSchemaRef, getModelSchemaRef,
getWhereSchemaFor, getWhereSchemaFor,
param, param,
patch, patch,
post, post,
requestBody, requestBody,
} from '@loopback/rest'; } from '@loopback/rest';
import { import {
Course, Course,
Requirement, Requirement,
} from '../models'; } from '../models';
import {CourseRepository} from '../repositories'; import { CourseRepository } from '../repositories';
export class CourseRequirementController { export class CourseRequirementController {
constructor( constructor(
@repository(CourseRepository) protected courseRepository: CourseRepository, @repository(CourseRepository) protected courseRepository: CourseRepository,
) { } ) {
}
@get('/courses/{id}/requirements', { @get('/courses/{id}/requirements', {
responses: { responses: {
'200': { '200': {
description: 'Array of Course has many Requirement', description: 'Array of Course has many Requirement',
content: { content: {
'application/json': { 'application/json': {
schema: {type: 'array', items: getModelSchemaRef(Requirement)}, schema: {type: 'array', items: getModelSchemaRef(Requirement)},
}, },
},
},
}, },
},
},
})
async find(
@param.path.number('id') id: number,
@param.query.object('filter') filter?: Filter<Requirement>,
): Promise<Requirement[]> {
return this.courseRepository.requirements(id).find(filter);
}
@post('/courses/{id}/requirements', {
responses: {
'200': {
description: 'Course model instance',
content: {'application/json': {schema: getModelSchemaRef(Requirement)}},
},
},
})
async create(
@param.path.number('id') id: typeof Course.prototype.id,
@requestBody({
content: {
'application/json': {
schema: getModelSchemaRef(Requirement, {
title: 'NewRequirementInCourse',
exclude: ['id'],
optional: ['courseId']
}),
},
},
}) requirement: Omit<Requirement, 'id'>,
): Promise<Requirement> {
return this.courseRepository.requirements(id).create(requirement);
}
@patch('/courses/{id}/requirements', {
responses: {
'200': {
description: 'Course.Requirement PATCH success count',
content: {'application/json': {schema: CountSchema}},
},
},
})
async patch(
@param.path.number('id') id: number,
@requestBody({
content: {
'application/json': {
schema: getModelSchemaRef(Requirement, {partial: true}),
},
},
}) })
requirement: Partial<Requirement>, async find(
@param.query.object('where', getWhereSchemaFor(Requirement)) where?: Where<Requirement>, @param.path.number('id') id: number,
): Promise<Count> { @param.query.object('filter') filter?: Filter<Requirement>,
return this.courseRepository.requirements(id).patch(requirement, where); ): Promise<Requirement[]> {
} return this.courseRepository.requirements(id).find(filter);
}
@del('/courses/{id}/requirements', { @post('/courses/{id}/requirements', {
responses: { responses: {
'200': { '200': {
description: 'Course.Requirement DELETE success count', description: 'Course model instance',
content: {'application/json': {schema: CountSchema}}, content: {'application/json': {schema: getModelSchemaRef(Requirement)}},
}, },
}, },
}) })
async delete( async create(
@param.path.number('id') id: number, @param.path.number('id') id: typeof Course.prototype.id,
@param.query.object('where', getWhereSchemaFor(Requirement)) where?: Where<Requirement>, @requestBody({
): Promise<Count> { content: {
return this.courseRepository.requirements(id).delete(where); 'application/json': {
} schema: getModelSchemaRef(Requirement, {
title: 'NewRequirementInCourse',
exclude: ['id'],
optional: ['courseId']
}),
},
},
}) requirement: Omit<Requirement, 'id'>,
): Promise<Requirement> {
return this.courseRepository.requirements(id).create(requirement);
}
@patch('/courses/{id}/requirements', {
responses: {
'200': {
description: 'Course.Requirement PATCH success count',
content: {'application/json': {schema: CountSchema}},
},
},
})
async patch(
@param.path.number('id') id: number,
@requestBody({
content: {
'application/json': {
schema: getModelSchemaRef(Requirement, {partial: true}),
},
},
})
requirement: Partial<Requirement>,
@param.query.object('where', getWhereSchemaFor(Requirement)) where?: Where<Requirement>,
): Promise<Count> {
return this.courseRepository.requirements(id).patch(requirement, where);
}
@del('/courses/{id}/requirements', {
responses: {
'200': {
description: 'Course.Requirement DELETE success count',
content: {'application/json': {schema: CountSchema}},
},
},
})
async delete(
@param.path.number('id') id: number,
@param.query.object('where', getWhereSchemaFor(Requirement)) where?: Where<Requirement>,
): Promise<Count> {
return this.courseRepository.requirements(id).delete(where);
}
} }

View file

@ -1,38 +1,39 @@
import { import {
repository, repository,
} from '@loopback/repository'; } from '@loopback/repository';
import { import {
param, param,
get, get,
getModelSchemaRef, getModelSchemaRef,
} from '@loopback/rest'; } from '@loopback/rest';
import { import {
Course, Course,
Subject, Subject,
} from '../models'; } from '../models';
import {CourseRepository} from '../repositories'; import { CourseRepository } from '../repositories';
export class CourseSubjectController { export class CourseSubjectController {
constructor( constructor(
@repository(CourseRepository) @repository(CourseRepository)
public courseRepository: CourseRepository, public courseRepository: CourseRepository,
) { } ) {
}
@get('/courses/{id}/subject', { @get('/courses/{id}/subject', {
responses: { responses: {
'200': { '200': {
description: 'Subject belonging to Course', description: 'Subject belonging to Course',
content: { content: {
'application/json': { 'application/json': {
schema: {type: 'array', items: getModelSchemaRef(Subject)}, schema: {type: 'array', items: getModelSchemaRef(Subject)},
}, },
},
},
}, },
}, })
}, async getSubject(
}) @param.path.number('id') id: typeof Course.prototype.id,
async getSubject( ): Promise<Subject> {
@param.path.number('id') id: typeof Course.prototype.id, return this.courseRepository.subject(id);
): Promise<Subject> { }
return this.courseRepository.subject(id);
}
} }

View file

@ -1,109 +1,110 @@
import { import {
Count, Count,
CountSchema, CountSchema,
Filter, Filter,
repository, repository,
Where, Where,
} from '@loopback/repository'; } from '@loopback/repository';
import { import {
del, del,
get, get,
getModelSchemaRef, getModelSchemaRef,
getWhereSchemaFor, getWhereSchemaFor,
param, param,
patch, patch,
post, post,
requestBody, requestBody,
} from '@loopback/rest'; } from '@loopback/rest';
import { import {
Course, Course,
User, User,
} from '../models'; } from '../models';
import {CourseRepository} from '../repositories'; import { CourseRepository } from '../repositories';
export class CourseUserController { export class CourseUserController {
constructor( constructor(
@repository(CourseRepository) protected courseRepository: CourseRepository, @repository(CourseRepository) protected courseRepository: CourseRepository,
) { } ) {
}
@get('/courses/{id}/users', { @get('/courses/{id}/users', {
responses: { responses: {
'200': { '200': {
description: 'Array of Course has many User through CourseUser', description: 'Array of Course has many User through CourseUser',
content: { content: {
'application/json': { 'application/json': {
schema: {type: 'array', items: getModelSchemaRef(User)}, schema: {type: 'array', items: getModelSchemaRef(User)},
}, },
},
},
}, },
},
},
})
async find(
@param.path.number('id') id: number,
@param.query.object('filter') filter?: Filter<User>,
): Promise<User[]> {
return this.courseRepository.users(id).find(filter);
}
@post('/courses/{id}/users', {
responses: {
'200': {
description: 'create a User model instance',
content: {'application/json': {schema: getModelSchemaRef(User)}},
},
},
})
async create(
@param.path.number('id') id: typeof Course.prototype.id,
@requestBody({
content: {
'application/json': {
schema: getModelSchemaRef(User, {
title: 'NewUserInCourse',
exclude: ['id'],
}),
},
},
}) user: Omit<User, 'id'>,
): Promise<User> {
return this.courseRepository.users(id).create(user);
}
@patch('/courses/{id}/users', {
responses: {
'200': {
description: 'Course.User PATCH success count',
content: {'application/json': {schema: CountSchema}},
},
},
})
async patch(
@param.path.number('id') id: number,
@requestBody({
content: {
'application/json': {
schema: getModelSchemaRef(User, {partial: true}),
},
},
}) })
user: Partial<User>, async find(
@param.query.object('where', getWhereSchemaFor(User)) where?: Where<User>, @param.path.number('id') id: number,
): Promise<Count> { @param.query.object('filter') filter?: Filter<User>,
return this.courseRepository.users(id).patch(user, where); ): Promise<User[]> {
} return this.courseRepository.users(id).find(filter);
}
@del('/courses/{id}/users', { @post('/courses/{id}/users', {
responses: { responses: {
'200': { '200': {
description: 'Course.User DELETE success count', description: 'create a User model instance',
content: {'application/json': {schema: CountSchema}}, content: {'application/json': {schema: getModelSchemaRef(User)}},
}, },
}, },
}) })
async delete( async create(
@param.path.number('id') id: number, @param.path.number('id') id: typeof Course.prototype.id,
@param.query.object('where', getWhereSchemaFor(User)) where?: Where<User>, @requestBody({
): Promise<Count> { content: {
return this.courseRepository.users(id).delete(where); 'application/json': {
} schema: getModelSchemaRef(User, {
title: 'NewUserInCourse',
exclude: ['id'],
}),
},
},
}) user: Omit<User, 'id'>,
): Promise<User> {
return this.courseRepository.users(id).create(user);
}
@patch('/courses/{id}/users', {
responses: {
'200': {
description: 'Course.User PATCH success count',
content: {'application/json': {schema: CountSchema}},
},
},
})
async patch(
@param.path.number('id') id: number,
@requestBody({
content: {
'application/json': {
schema: getModelSchemaRef(User, {partial: true}),
},
},
})
user: Partial<User>,
@param.query.object('where', getWhereSchemaFor(User)) where?: Where<User>,
): Promise<Count> {
return this.courseRepository.users(id).patch(user, where);
}
@del('/courses/{id}/users', {
responses: {
'200': {
description: 'Course.User DELETE success count',
content: {'application/json': {schema: CountSchema}},
},
},
})
async delete(
@param.path.number('id') id: number,
@param.query.object('where', getWhereSchemaFor(User)) where?: Where<User>,
): Promise<Count> {
return this.courseRepository.users(id).delete(where);
}
} }

View file

@ -1,110 +1,111 @@
import { import {
Count, Count,
CountSchema, CountSchema,
Filter, Filter,
repository, repository,
Where, Where,
} from '@loopback/repository'; } from '@loopback/repository';
import { import {
del, del,
get, get,
getModelSchemaRef, getModelSchemaRef,
getWhereSchemaFor, getWhereSchemaFor,
param, param,
patch, patch,
post, post,
requestBody, requestBody,
} from '@loopback/rest'; } from '@loopback/rest';
import { import {
Subject, Subject,
Course, Course,
} from '../models'; } from '../models';
import {SubjectRepository} from '../repositories'; import { SubjectRepository } from '../repositories';
export class SubjectCourseController { export class SubjectCourseController {
constructor( constructor(
@repository(SubjectRepository) protected subjectRepository: SubjectRepository, @repository(SubjectRepository) protected subjectRepository: SubjectRepository,
) { } ) {
}
@get('/subjects/{id}/courses', { @get('/subjects/{id}/courses', {
responses: { responses: {
'200': { '200': {
description: 'Array of Subject has many Course', description: 'Array of Subject has many Course',
content: { content: {
'application/json': { 'application/json': {
schema: {type: 'array', items: getModelSchemaRef(Course)}, schema: {type: 'array', items: getModelSchemaRef(Course)},
}, },
},
},
}, },
},
},
})
async find(
@param.path.number('id') id: number,
@param.query.object('filter') filter?: Filter<Course>,
): Promise<Course[]> {
return this.subjectRepository.courses(id).find(filter);
}
@post('/subjects/{id}/courses', {
responses: {
'200': {
description: 'Subject model instance',
content: {'application/json': {schema: getModelSchemaRef(Course)}},
},
},
})
async create(
@param.path.number('id') id: typeof Subject.prototype.id,
@requestBody({
content: {
'application/json': {
schema: getModelSchemaRef(Course, {
title: 'NewCourseInSubject',
exclude: ['id'],
optional: ['subjectId']
}),
},
},
}) course: Omit<Course, 'id'>,
): Promise<Course> {
return this.subjectRepository.courses(id).create(course);
}
@patch('/subjects/{id}/courses', {
responses: {
'200': {
description: 'Subject.Course PATCH success count',
content: {'application/json': {schema: CountSchema}},
},
},
})
async patch(
@param.path.number('id') id: number,
@requestBody({
content: {
'application/json': {
schema: getModelSchemaRef(Course, {partial: true}),
},
},
}) })
course: Partial<Course>, async find(
@param.query.object('where', getWhereSchemaFor(Course)) where?: Where<Course>, @param.path.number('id') id: number,
): Promise<Count> { @param.query.object('filter') filter?: Filter<Course>,
return this.subjectRepository.courses(id).patch(course, where); ): Promise<Course[]> {
} return this.subjectRepository.courses(id).find(filter);
}
@del('/subjects/{id}/courses', { @post('/subjects/{id}/courses', {
responses: { responses: {
'200': { '200': {
description: 'Subject.Course DELETE success count', description: 'Subject model instance',
content: {'application/json': {schema: CountSchema}}, content: {'application/json': {schema: getModelSchemaRef(Course)}},
}, },
}, },
}) })
async delete( async create(
@param.path.number('id') id: number, @param.path.number('id') id: typeof Subject.prototype.id,
@param.query.object('where', getWhereSchemaFor(Course)) where?: Where<Course>, @requestBody({
): Promise<Count> { content: {
return this.subjectRepository.courses(id).delete(where); 'application/json': {
} schema: getModelSchemaRef(Course, {
title: 'NewCourseInSubject',
exclude: ['id'],
optional: ['subjectId']
}),
},
},
}) course: Omit<Course, 'id'>,
): Promise<Course> {
return this.subjectRepository.courses(id).create(course);
}
@patch('/subjects/{id}/courses', {
responses: {
'200': {
description: 'Subject.Course PATCH success count',
content: {'application/json': {schema: CountSchema}},
},
},
})
async patch(
@param.path.number('id') id: number,
@requestBody({
content: {
'application/json': {
schema: getModelSchemaRef(Course, {partial: true}),
},
},
})
course: Partial<Course>,
@param.query.object('where', getWhereSchemaFor(Course)) where?: Where<Course>,
): Promise<Count> {
return this.subjectRepository.courses(id).patch(course, where);
}
@del('/subjects/{id}/courses', {
responses: {
'200': {
description: 'Subject.Course DELETE success count',
content: {'application/json': {schema: CountSchema}},
},
},
})
async delete(
@param.path.number('id') id: number,
@param.query.object('where', getWhereSchemaFor(Course)) where?: Where<Course>,
): Promise<Count> {
return this.subjectRepository.courses(id).delete(where);
}
} }

View file

@ -1,109 +1,110 @@
import { import {
Count, Count,
CountSchema, CountSchema,
Filter, Filter,
repository, repository,
Where, Where,
} from '@loopback/repository'; } from '@loopback/repository';
import { import {
del, del,
get, get,
getModelSchemaRef, getModelSchemaRef,
getWhereSchemaFor, getWhereSchemaFor,
param, param,
patch, patch,
post, post,
requestBody, requestBody,
} from '@loopback/rest'; } from '@loopback/rest';
import { import {
User, User,
Course, Course,
} from '../models'; } from '../models';
import {UserRepository} from '../repositories'; import { UserRepository } from '../repositories';
export class UserCourseController { export class UserCourseController {
constructor( constructor(
@repository(UserRepository) protected userRepository: UserRepository, @repository(UserRepository) protected userRepository: UserRepository,
) { } ) {
}
@get('/users/{id}/courses', { @get('/users/{id}/courses', {
responses: { responses: {
'200': { '200': {
description: 'Array of User has many Course through CourseUser', description: 'Array of User has many Course through CourseUser',
content: { content: {
'application/json': { 'application/json': {
schema: {type: 'array', items: getModelSchemaRef(Course)}, schema: {type: 'array', items: getModelSchemaRef(Course)},
}, },
},
},
}, },
},
},
})
async find(
@param.path.number('id') id: number,
@param.query.object('filter') filter?: Filter<Course>,
): Promise<Course[]> {
return this.userRepository.courses(id).find(filter);
}
@post('/users/{id}/courses', {
responses: {
'200': {
description: 'create a Course model instance',
content: {'application/json': {schema: getModelSchemaRef(Course)}},
},
},
})
async create(
@param.path.number('id') id: typeof User.prototype.id,
@requestBody({
content: {
'application/json': {
schema: getModelSchemaRef(Course, {
title: 'NewCourseInUser',
exclude: ['id'],
}),
},
},
}) course: Omit<Course, 'id'>,
): Promise<Course> {
return this.userRepository.courses(id).create(course);
}
@patch('/users/{id}/courses', {
responses: {
'200': {
description: 'User.Course PATCH success count',
content: {'application/json': {schema: CountSchema}},
},
},
})
async patch(
@param.path.number('id') id: number,
@requestBody({
content: {
'application/json': {
schema: getModelSchemaRef(Course, {partial: true}),
},
},
}) })
course: Partial<Course>, async find(
@param.query.object('where', getWhereSchemaFor(Course)) where?: Where<Course>, @param.path.number('id') id: number,
): Promise<Count> { @param.query.object('filter') filter?: Filter<Course>,
return this.userRepository.courses(id).patch(course, where); ): Promise<Course[]> {
} return this.userRepository.courses(id).find(filter);
}
@del('/users/{id}/courses', { @post('/users/{id}/courses', {
responses: { responses: {
'200': { '200': {
description: 'User.Course DELETE success count', description: 'create a Course model instance',
content: {'application/json': {schema: CountSchema}}, content: {'application/json': {schema: getModelSchemaRef(Course)}},
}, },
}, },
}) })
async delete( async create(
@param.path.number('id') id: number, @param.path.number('id') id: typeof User.prototype.id,
@param.query.object('where', getWhereSchemaFor(Course)) where?: Where<Course>, @requestBody({
): Promise<Count> { content: {
return this.userRepository.courses(id).delete(where); 'application/json': {
} schema: getModelSchemaRef(Course, {
title: 'NewCourseInUser',
exclude: ['id'],
}),
},
},
}) course: Omit<Course, 'id'>,
): Promise<Course> {
return this.userRepository.courses(id).create(course);
}
@patch('/users/{id}/courses', {
responses: {
'200': {
description: 'User.Course PATCH success count',
content: {'application/json': {schema: CountSchema}},
},
},
})
async patch(
@param.path.number('id') id: number,
@requestBody({
content: {
'application/json': {
schema: getModelSchemaRef(Course, {partial: true}),
},
},
})
course: Partial<Course>,
@param.query.object('where', getWhereSchemaFor(Course)) where?: Where<Course>,
): Promise<Count> {
return this.userRepository.courses(id).patch(course, where);
}
@del('/users/{id}/courses', {
responses: {
'200': {
description: 'User.Course DELETE success count',
content: {'application/json': {schema: CountSchema}},
},
},
})
async delete(
@param.path.number('id') id: number,
@param.query.object('where', getWhereSchemaFor(Course)) where?: Where<Course>,
): Promise<Count> {
return this.userRepository.courses(id).delete(where);
}
} }

View file

@ -1,16 +1,16 @@
import {Count, CountSchema, Filter, FilterExcludingWhere, repository, Where,} from '@loopback/repository'; import { Count, CountSchema, Filter, FilterExcludingWhere, repository, Where, } from '@loopback/repository';
import { del, get, getModelSchemaRef, HttpErrors, param, patch, post, Request, requestBody, response, RestBindings, } from '@loopback/rest'; import { del, get, getModelSchemaRef, HttpErrors, param, patch, post, Request, requestBody, response, RestBindings, } from '@loopback/rest';
import {User} from '../models'; import { User } from '../models';
import {UserRepository} from '../repositories'; import { UserRepository } from '../repositories';
import { import {
TokenServiceBindings, TokenServiceBindings,
UserServiceBindings UserServiceBindings
} from '@loopback/authentication-jwt'; } from '@loopback/authentication-jwt';
import {inject} from '@loopback/core'; import { inject } from '@loopback/core';
import {authenticate, TokenService} from '@loopback/authentication'; import { authenticate, TokenService } from '@loopback/authentication';
import {SecurityBindings, UserProfile} from '@loopback/security'; import { SecurityBindings, UserProfile } from '@loopback/security';
import {genSalt, hash} from 'bcryptjs'; import { genSalt, hash } from 'bcryptjs';
import {SzakdolgozatUserService} from '../services'; import { SzakdolgozatUserService } from '../services';
export class UserController { export class UserController {
constructor( constructor(
@ -197,10 +197,11 @@ export class UserController {
}) })
user: User, user: User,
): Promise<void> { ): Promise<void> {
if(id === +this.user.id) { if (id === +this.user.id) {
const loggedInUser = await this.userService.findUserById(this.user.id); const loggedInUser = await this.userService.findUserById(this.user.id);
if(user.isAdmin !== undefined && loggedInUser.isAdmin !== user.isAdmin) if (user.isAdmin !== undefined && loggedInUser.isAdmin !== user.isAdmin) {
throw new HttpErrors.BadRequest('Cannot change admin status of self'); throw new HttpErrors.BadRequest('Cannot change admin status of self');
}
} }
await this.userRepository.updateById(id, user); await this.userRepository.updateById(id, user);
} }

View file

@ -1,40 +1,40 @@
import {Entity, model, property} from '@loopback/repository'; import { Entity, model, property } from '@loopback/repository';
@model() @model()
export class CourseUser extends Entity { export class CourseUser extends Entity {
@property({ @property({
type: 'number', type: 'number',
id: true, id: true,
generated: true, generated: true,
}) })
id?: number; id?: number;
@property({ @property({
type: 'number', type: 'number',
required: true, required: true,
}) })
courseId: number; courseId: number;
@property({ @property({
type: 'number', type: 'number',
required: true, required: true,
}) })
userId: number; userId: number;
@property({ @property({
type: 'string', type: 'string',
required: true, required: true,
}) })
role: string; role: string;
constructor(data?: Partial<CourseUser>) { constructor(data?: Partial<CourseUser>) {
super(data); super(data);
} }
} }
export interface CourseUserRelations { export interface CourseUserRelations {
// describe navigational properties here // describe navigational properties here
} }
export type CourseUserWithRelations = CourseUser & CourseUserRelations; export type CourseUserWithRelations = CourseUser & CourseUserRelations;

View file

@ -1,40 +1,40 @@
import {Entity, model, property, belongsTo, hasMany} from '@loopback/repository'; import { Entity, model, property, belongsTo, hasMany } from '@loopback/repository';
import {Subject} from './subject.model'; import { Subject } from './subject.model';
import {User} from './user.model'; import { User } from './user.model';
import {CourseUser} from './course-user.model'; import { CourseUser } from './course-user.model';
import {Requirement} from './requirement.model'; import { Requirement } from './requirement.model';
@model() @model()
export class Course extends Entity { export class Course extends Entity {
@property({ @property({
type: 'number', type: 'number',
id: true, id: true,
generated: true, generated: true,
}) })
id?: number; id?: number;
@property({ @property({
type: 'string', type: 'string',
required: true, required: true,
}) })
semester: string; semester: string;
@belongsTo(() => Subject) @belongsTo(() => Subject)
subjectId: number; subjectId: number;
@hasMany(() => User, {through: {model: () => CourseUser}}) @hasMany(() => User, {through: {model: () => CourseUser}})
users: User[]; users: User[];
@hasMany(() => Requirement) @hasMany(() => Requirement)
requirements: Requirement[]; requirements: Requirement[];
constructor(data?: Partial<Course>) { constructor(data?: Partial<Course>) {
super(data); super(data);
} }
} }
export interface CourseRelations { export interface CourseRelations {
// describe navigational properties here // describe navigational properties here
} }
export type CourseWithRelations = Course & CourseRelations; export type CourseWithRelations = Course & CourseRelations;

View file

@ -1,44 +1,44 @@
import {Entity, model, property} from '@loopback/repository'; import { Entity, model, property } from '@loopback/repository';
@model() @model()
export class Requirement extends Entity { export class Requirement extends Entity {
@property({ @property({
type: 'number', type: 'number',
id: true, id: true,
generated: true, generated: true,
}) })
id?: number; id?: number;
@property({ @property({
type: 'string', type: 'string',
required: true, required: true,
}) })
name: string; name: string;
@property({ @property({
type: 'number', type: 'number',
required: true, required: true,
}) })
maxPoints: number; maxPoints: number;
@property({ @property({
type: 'string', type: 'string',
required: true, required: true,
}) })
type: string; type: string;
@property({ @property({
type: 'number', type: 'number',
}) })
courseId?: number; courseId?: number;
constructor(data?: Partial<Requirement>) { constructor(data?: Partial<Requirement>) {
super(data); super(data);
} }
} }
export interface RequirementRelations { export interface RequirementRelations {
// describe navigational properties here // describe navigational properties here
} }
export type RequirementWithRelations = Requirement & RequirementRelations; export type RequirementWithRelations = Requirement & RequirementRelations;

View file

@ -1,36 +1,36 @@
import {Entity, model, property, hasMany} from '@loopback/repository'; import { Entity, model, property, hasMany } from '@loopback/repository';
import {Course} from './course.model'; import { Course } from './course.model';
@model() @model()
export class Subject extends Entity { export class Subject extends Entity {
@property({ @property({
type: 'number', type: 'number',
id: true, id: true,
generated: true, generated: true,
}) })
id?: number; id?: number;
@property({ @property({
type: 'string', type: 'string',
required: true, required: true,
}) })
name: string; name: string;
@property({ @property({
type: 'string', type: 'string',
}) })
description?: string; description?: string;
@hasMany(() => Course) @hasMany(() => Course)
courses: Course[]; courses: Course[];
constructor(data?: Partial<Subject>) { constructor(data?: Partial<Subject>) {
super(data); super(data);
} }
} }
export interface SubjectRelations { export interface SubjectRelations {
// describe navigational properties here // describe navigational properties here
} }
export type SubjectWithRelations = Subject & SubjectRelations; export type SubjectWithRelations = Subject & SubjectRelations;

View file

@ -1,61 +1,61 @@
import {Entity, model, property, hasMany} from '@loopback/repository'; import { Entity, model, property, hasMany } from '@loopback/repository';
import {Course} from './course.model'; import { Course } from './course.model';
import {CourseUser} from './course-user.model'; import { CourseUser } from './course-user.model';
@model() @model()
export class User extends Entity { export class User extends Entity {
@property({ @property({
type: 'number', type: 'number',
id: true, id: true,
generated: true, generated: true,
}) })
id?: number; id?: number;
@property({ @property({
type: 'string', type: 'string',
required: true, required: true,
jsonSchema: { jsonSchema: {
pattern: /[A-Za-z0-9.+_-]+@[A-Za-z.-_]*(u-szeged.hu)|(szte.hu)/.source pattern: /[A-Za-z0-9.+_-]+@[A-Za-z.-_]*(u-szeged.hu)|(szte.hu)/.source
}
})
email: string;
@property({
type: 'string',
required: true,
jsonSchema: {
pattern: /([A-Za-z-.]+ )+[A-Za-z-.]+/.source
}
})
name: string;
@property({
type: 'string',
required: true,
jsonSchema: {
minLength: 8,
maxLength: 255
},
hidden: true
})
password: string;
@property({
type: 'boolean',
required: true,
})
isAdmin: boolean;
@hasMany(() => Course, {through: {model: () => CourseUser}})
courses: Course[];
constructor(data?: Partial<User>) {
super(data);
} }
})
email: string;
@property({
type: 'string',
required: true,
jsonSchema: {
pattern: /([A-Za-z-.]+ )+[A-Za-z-.]+/.source
}
})
name: string;
@property({
type: 'string',
required: true,
jsonSchema: {
minLength: 8,
maxLength: 255
},
hidden: true
})
password: string;
@property({
type: 'boolean',
required: true,
})
isAdmin: boolean;
@hasMany(() => Course, {through: {model: () => CourseUser}})
courses: Course[];
constructor(data?: Partial<User>) {
super(data);
}
} }
export interface UserRelations { export interface UserRelations {
// describe navigational properties here // describe navigational properties here
} }
export type UserWithRelations = User & UserRelations; export type UserWithRelations = User & UserRelations;

View file

@ -1,16 +1,14 @@
import {inject} from '@loopback/core'; import { inject } from '@loopback/core';
import {DefaultCrudRepository} from '@loopback/repository'; import { DefaultCrudRepository } from '@loopback/repository';
import {DatabaseDataSource} from '../datasources'; import { DatabaseDataSource } from '../datasources';
import {CourseUser, CourseUserRelations} from '../models'; import { CourseUser, CourseUserRelations } from '../models';
export class CourseUserRepository extends DefaultCrudRepository< export class CourseUserRepository extends DefaultCrudRepository<CourseUser,
CourseUser, typeof CourseUser.prototype.id,
typeof CourseUser.prototype.id, CourseUserRelations> {
CourseUserRelations constructor(
> { @inject('datasources.database') dataSource: DatabaseDataSource,
constructor( ) {
@inject('datasources.database') dataSource: DatabaseDataSource, super(CourseUser, dataSource);
) { }
super(CourseUser, dataSource);
}
} }

View file

@ -1,36 +1,39 @@
import {inject, Getter} from '@loopback/core'; import { inject, Getter } from '@loopback/core';
import {DefaultCrudRepository, repository, BelongsToAccessor, HasManyThroughRepositoryFactory, HasManyRepositoryFactory} from '@loopback/repository'; import {
import {DatabaseDataSource} from '../datasources'; DefaultCrudRepository,
import {Course, CourseRelations, Subject, User, CourseUser, Requirement} from '../models'; repository,
import {SubjectRepository} from './subject.repository'; BelongsToAccessor,
import {CourseUserRepository} from './course-user.repository'; HasManyThroughRepositoryFactory,
import {UserRepository} from './user.repository'; HasManyRepositoryFactory
import {RequirementRepository} from './requirement.repository'; } from '@loopback/repository';
import { DatabaseDataSource } from '../datasources';
import { Course, CourseRelations, Subject, User, CourseUser, Requirement } from '../models';
import { SubjectRepository } from './subject.repository';
import { CourseUserRepository } from './course-user.repository';
import { UserRepository } from './user.repository';
import { RequirementRepository } from './requirement.repository';
export class CourseRepository extends DefaultCrudRepository< export class CourseRepository extends DefaultCrudRepository<Course,
Course, typeof Course.prototype.id,
typeof Course.prototype.id, CourseRelations> {
CourseRelations
> {
public readonly subject: BelongsToAccessor<Subject, typeof Course.prototype.id>; public readonly subject: BelongsToAccessor<Subject, typeof Course.prototype.id>;
public readonly users: HasManyThroughRepositoryFactory<User, typeof User.prototype.id, public readonly users: HasManyThroughRepositoryFactory<User, typeof User.prototype.id,
CourseUser, CourseUser,
typeof Course.prototype.id typeof Course.prototype.id>;
>;
public readonly requirements: HasManyRepositoryFactory<Requirement, typeof Course.prototype.id>; public readonly requirements: HasManyRepositoryFactory<Requirement, typeof Course.prototype.id>;
constructor( constructor(
@inject('datasources.database') dataSource: DatabaseDataSource, @repository.getter('SubjectRepository') protected subjectRepositoryGetter: Getter<SubjectRepository>, @repository.getter('CourseUserRepository') protected courseUserRepositoryGetter: Getter<CourseUserRepository>, @repository.getter('UserRepository') protected userRepositoryGetter: Getter<UserRepository>, @repository.getter('RequirementRepository') protected requirementRepositoryGetter: Getter<RequirementRepository>, @inject('datasources.database') dataSource: DatabaseDataSource, @repository.getter('SubjectRepository') protected subjectRepositoryGetter: Getter<SubjectRepository>, @repository.getter('CourseUserRepository') protected courseUserRepositoryGetter: Getter<CourseUserRepository>, @repository.getter('UserRepository') protected userRepositoryGetter: Getter<UserRepository>, @repository.getter('RequirementRepository') protected requirementRepositoryGetter: Getter<RequirementRepository>,
) { ) {
super(Course, dataSource); super(Course, dataSource);
this.requirements = this.createHasManyRepositoryFactoryFor('requirements', requirementRepositoryGetter,); this.requirements = this.createHasManyRepositoryFactoryFor('requirements', requirementRepositoryGetter,);
this.registerInclusionResolver('requirements', this.requirements.inclusionResolver); this.registerInclusionResolver('requirements', this.requirements.inclusionResolver);
this.users = this.createHasManyThroughRepositoryFactoryFor('users', userRepositoryGetter, courseUserRepositoryGetter,); this.users = this.createHasManyThroughRepositoryFactoryFor('users', userRepositoryGetter, courseUserRepositoryGetter,);
this.registerInclusionResolver('users', this.users.inclusionResolver); this.registerInclusionResolver('users', this.users.inclusionResolver);
this.subject = this.createBelongsToAccessorFor('subject', subjectRepositoryGetter,); this.subject = this.createBelongsToAccessorFor('subject', subjectRepositoryGetter,);
this.registerInclusionResolver('subject', this.subject.inclusionResolver); this.registerInclusionResolver('subject', this.subject.inclusionResolver);
} }
} }

View file

@ -1,16 +1,14 @@
import {inject} from '@loopback/core'; import { inject } from '@loopback/core';
import {DefaultCrudRepository} from '@loopback/repository'; import { DefaultCrudRepository } from '@loopback/repository';
import {DatabaseDataSource} from '../datasources'; import { DatabaseDataSource } from '../datasources';
import {Requirement, RequirementRelations} from '../models'; import { Requirement, RequirementRelations } from '../models';
export class RequirementRepository extends DefaultCrudRepository< export class RequirementRepository extends DefaultCrudRepository<Requirement,
Requirement, typeof Requirement.prototype.id,
typeof Requirement.prototype.id, RequirementRelations> {
RequirementRelations constructor(
> { @inject('datasources.database') dataSource: DatabaseDataSource,
constructor( ) {
@inject('datasources.database') dataSource: DatabaseDataSource, super(Requirement, dataSource);
) { }
super(Requirement, dataSource);
}
} }

View file

@ -1,23 +1,21 @@
import {inject, Getter} from '@loopback/core'; import { inject, Getter } from '@loopback/core';
import {DefaultCrudRepository, repository, HasManyRepositoryFactory} from '@loopback/repository'; import { DefaultCrudRepository, repository, HasManyRepositoryFactory } from '@loopback/repository';
import {DatabaseDataSource} from '../datasources'; import { DatabaseDataSource } from '../datasources';
import {Subject, SubjectRelations, Course} from '../models'; import { Subject, SubjectRelations, Course } from '../models';
import {UserRepository} from './user.repository'; import { UserRepository } from './user.repository';
import {CourseRepository} from './course.repository'; import { CourseRepository } from './course.repository';
export class SubjectRepository extends DefaultCrudRepository< export class SubjectRepository extends DefaultCrudRepository<Subject,
Subject, typeof Subject.prototype.id,
typeof Subject.prototype.id, SubjectRelations> {
SubjectRelations
> {
public readonly courses: HasManyRepositoryFactory<Course, typeof Subject.prototype.id>; public readonly courses: HasManyRepositoryFactory<Course, typeof Subject.prototype.id>;
constructor( constructor(
@inject('datasources.database') dataSource: DatabaseDataSource, @repository.getter('UserRepository') protected userRepositoryGetter: Getter<UserRepository>, @repository.getter('CourseRepository') protected courseRepositoryGetter: Getter<CourseRepository>, @inject('datasources.database') dataSource: DatabaseDataSource, @repository.getter('UserRepository') protected userRepositoryGetter: Getter<UserRepository>, @repository.getter('CourseRepository') protected courseRepositoryGetter: Getter<CourseRepository>,
) { ) {
super(Subject, dataSource); super(Subject, dataSource);
this.courses = this.createHasManyRepositoryFactoryFor('courses', courseRepositoryGetter,); this.courses = this.createHasManyRepositoryFactoryFor('courses', courseRepositoryGetter,);
this.registerInclusionResolver('courses', this.courses.inclusionResolver); this.registerInclusionResolver('courses', this.courses.inclusionResolver);
} }
} }

View file

@ -1,27 +1,24 @@
import {inject, Getter} from '@loopback/core'; import { inject, Getter } from '@loopback/core';
import { repository, HasManyThroughRepositoryFactory, DefaultTransactionalRepository } from '@loopback/repository'; import { repository, HasManyThroughRepositoryFactory, DefaultTransactionalRepository } from '@loopback/repository';
import {DatabaseDataSource} from '../datasources'; import { DatabaseDataSource } from '../datasources';
import {User, UserRelations, Course, CourseUser} from '../models'; import { User, UserRelations, Course, CourseUser } from '../models';
import {SubjectRepository} from './subject.repository'; import { SubjectRepository } from './subject.repository';
import {CourseUserRepository} from './course-user.repository'; import { CourseUserRepository } from './course-user.repository';
import {CourseRepository} from './course.repository'; import { CourseRepository } from './course.repository';
export class UserRepository extends DefaultTransactionalRepository< export class UserRepository extends DefaultTransactionalRepository<User,
User, typeof User.prototype.id,
typeof User.prototype.id, UserRelations> {
UserRelations
> {
public readonly courses: HasManyThroughRepositoryFactory<Course, typeof Course.prototype.id, public readonly courses: HasManyThroughRepositoryFactory<Course, typeof Course.prototype.id,
CourseUser, CourseUser,
typeof User.prototype.id typeof User.prototype.id>;
>;
constructor( constructor(
@inject('datasources.database') dataSource: DatabaseDataSource, @repository.getter('SubjectRepository') protected subjectRepositoryGetter: Getter<SubjectRepository>, @repository.getter('CourseUserRepository') protected courseUserRepositoryGetter: Getter<CourseUserRepository>, @repository.getter('CourseRepository') protected courseRepositoryGetter: Getter<CourseRepository>, @inject('datasources.database') dataSource: DatabaseDataSource, @repository.getter('SubjectRepository') protected subjectRepositoryGetter: Getter<SubjectRepository>, @repository.getter('CourseUserRepository') protected courseUserRepositoryGetter: Getter<CourseUserRepository>, @repository.getter('CourseRepository') protected courseRepositoryGetter: Getter<CourseRepository>,
) { ) {
super(User, dataSource); super(User, dataSource);
this.courses = this.createHasManyThroughRepositoryFactoryFor('courses', courseRepositoryGetter, courseUserRepositoryGetter,); this.courses = this.createHasManyThroughRepositoryFactoryFor('courses', courseRepositoryGetter, courseUserRepositoryGetter,);
this.registerInclusionResolver('courses', this.courses.inclusionResolver); this.registerInclusionResolver('courses', this.courses.inclusionResolver);
} }
} }

View file

@ -3,67 +3,68 @@
// This file is licensed under the MIT License. // This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT // License text available at https://opensource.org/licenses/MIT
import {UserService} from '@loopback/authentication'; import { UserService } from '@loopback/authentication';
import {repository} from '@loopback/repository'; import { repository } from '@loopback/repository';
import {HttpErrors} from '@loopback/rest'; import { HttpErrors } from '@loopback/rest';
import {securityId, UserProfile} from '@loopback/security'; import { securityId, UserProfile } from '@loopback/security';
import {compare} from 'bcryptjs'; import { compare } from 'bcryptjs';
import {User, UserWithRelations} from '../models'; import { User, UserWithRelations } from '../models';
import {UserRepository} from '../repositories'; import { UserRepository } from '../repositories';
/** /**
* A pre-defined type for user credentials. It assumes a user logs in * A pre-defined type for user credentials. It assumes a user logs in
* using the email and password. You can modify it if your app has different credential fields * using the email and password. You can modify it if your app has different credential fields
*/ */
export type Credentials = { export type Credentials = {
email: string; email: string;
password: string; password: string;
}; };
export class SzakdolgozatUserService implements UserService<User, Credentials> { export class SzakdolgozatUserService implements UserService<User, Credentials> {
constructor( constructor(
@repository(UserRepository) public userRepository: UserRepository, @repository(UserRepository) public userRepository: UserRepository,
) { } ) {
async verifyCredentials(credentials: Credentials): Promise<User> {
const invalidCredentialsError = 'Invalid email or password.';
const foundUser = await this.userRepository.findOne({
where: {email: credentials.email},
});
if (!foundUser) {
throw new HttpErrors.Unauthorized(invalidCredentialsError);
} }
const passwordMatched = await compare( async verifyCredentials(credentials: Credentials): Promise<User> {
credentials.password, const invalidCredentialsError = 'Invalid email or password.';
foundUser.password,
);
if (!passwordMatched) { const foundUser = await this.userRepository.findOne({
throw new HttpErrors.Unauthorized(invalidCredentialsError); where: {email: credentials.email},
});
if (!foundUser) {
throw new HttpErrors.Unauthorized(invalidCredentialsError);
}
const passwordMatched = await compare(
credentials.password,
foundUser.password,
);
if (!passwordMatched) {
throw new HttpErrors.Unauthorized(invalidCredentialsError);
}
return foundUser;
} }
return foundUser; convertToUserProfile({email, id, name}: User): UserProfile {
} return {
[securityId]: id!.toString(),
convertToUserProfile({email, id, name}: User): UserProfile { name,
return { id,
[securityId]: id!.toString(), email,
name, };
id, }
email,
}; //function to find user by id
} async findUserById(id: number): Promise<User & UserWithRelations> {
const userNotfound = 'invalid user';
//function to find user by id const foundUser = await this.userRepository.findById(id);
async findUserById(id: number): Promise<User & UserWithRelations> {
const userNotfound = 'invalid user'; if (!foundUser) {
const foundUser = await this.userRepository.findById(id); throw new HttpErrors.Unauthorized(userNotfound);
}
if (!foundUser) { return foundUser;
throw new HttpErrors.Unauthorized(userNotfound);
} }
return foundUser;
}
} }

View file

@ -10,7 +10,7 @@
</mat-nav-list> </mat-nav-list>
</mat-sidenav> </mat-sidenav>
<mat-sidenav-content> <mat-sidenav-content>
<mat-toolbar color="primary"> <mat-toolbar color="primary" style="z-index: 1000">
<button <button
type="button" type="button"
aria-label="Oldalsáv" aria-label="Oldalsáv"