mirror of
https://github.com/sergeyyarkov/educt-server.git
synced 2026-10-11 10:19:20 +03:00
some refactor
This commit is contained in:
parent
a9715971e4
commit
033eccdcc0
@ -13,18 +13,7 @@
|
||||
"Database": "database",
|
||||
"Contracts": "contracts"
|
||||
},
|
||||
"preloads": [
|
||||
"./start/routes",
|
||||
"./start/kernel"
|
||||
],
|
||||
"providers": [
|
||||
"./providers/AppProvider",
|
||||
"@adonisjs/core",
|
||||
"@adonisjs/lucid",
|
||||
"@adonisjs/auth",
|
||||
"@adonisjs/redis"
|
||||
],
|
||||
"aceProviders": [
|
||||
"@adonisjs/repl"
|
||||
]
|
||||
"preloads": ["./routes/index", "./start/kernel"],
|
||||
"providers": ["./providers/AppProvider", "@adonisjs/core", "@adonisjs/lucid", "@adonisjs/auth", "@adonisjs/redis"],
|
||||
"aceProviders": ["@adonisjs/repl"]
|
||||
}
|
||||
|
||||
@ -1,16 +1,20 @@
|
||||
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext';
|
||||
import Logger from '@ioc:Adonis/Core/Logger';
|
||||
import Hash from '@ioc:Adonis/Core/Hash';
|
||||
import User from 'App/Models/User';
|
||||
import { Exception } from '@adonisjs/core/build/standalone';
|
||||
|
||||
/**
|
||||
* Models
|
||||
*/
|
||||
import User from 'App/Models/User';
|
||||
|
||||
export default class AuthController {
|
||||
private user: typeof User;
|
||||
private User: typeof User;
|
||||
|
||||
private guard: 'api';
|
||||
|
||||
constructor() {
|
||||
this.user = User;
|
||||
this.User = User;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -21,7 +25,7 @@ export default class AuthController {
|
||||
public async login({ auth, request }: HttpContextContract) {
|
||||
const login = request.input('login');
|
||||
const password = request.input('password');
|
||||
const user = await this.user.query().preload('roles').where('login', login).firstOrFail();
|
||||
const user = await this.User.query().preload('roles').where('login', login).firstOrFail();
|
||||
|
||||
if (!(await Hash.verify(user.password, password))) {
|
||||
throw new Exception('Invalid credentials.', 403, 'E_INVALID_CREDENTIALS');
|
||||
|
||||
@ -1,7 +1,15 @@
|
||||
import { Exception } from '@adonisjs/core/build/standalone';
|
||||
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext';
|
||||
|
||||
/**
|
||||
* Models
|
||||
*/
|
||||
import Course from 'App/Models/Course';
|
||||
import User from 'App/Models/User';
|
||||
|
||||
/**
|
||||
* Validators
|
||||
*/
|
||||
import AddCourseToUserValidator from 'App/Validators/AddCourseToUserValidator';
|
||||
import CreateCourseValidator from 'App/Validators/CreateCourseValidator';
|
||||
import DelCourseFromUserValidator from 'App/Validators/DelCourseFromUserValidator';
|
||||
@ -21,7 +29,7 @@ export default class CoursesController {
|
||||
* List of all Courses
|
||||
* GET /courses
|
||||
*/
|
||||
public async index({ response }: HttpContextContract) {
|
||||
public async list({ response }: HttpContextContract) {
|
||||
const courses = await this.Course.query().preload('teacher').preload('category').preload('lessons');
|
||||
|
||||
return response.ok({
|
||||
@ -145,7 +153,7 @@ export default class CoursesController {
|
||||
* Delete Course by "id"
|
||||
* DELETE /courses/:id
|
||||
*/
|
||||
async destroy({ response, params }: HttpContextContract) {
|
||||
public async delete({ response, params }: HttpContextContract) {
|
||||
const course = await this.Course.query()
|
||||
.preload('teacher')
|
||||
.preload('category')
|
||||
@ -165,7 +173,7 @@ export default class CoursesController {
|
||||
* Update Course by "id"
|
||||
* PATCH /courses/:id
|
||||
*/
|
||||
async update({ response, request, params }: HttpContextContract) {
|
||||
public async update({ response, request, params }: HttpContextContract) {
|
||||
const payload = await request.validate(UpdateCourseValidator);
|
||||
const course = await this.Course.findOrFail(params.id);
|
||||
|
||||
@ -193,7 +201,7 @@ export default class CoursesController {
|
||||
* Attach student to course
|
||||
* POST /courses/:id/attach-student
|
||||
*/
|
||||
async attachStudent({ response, request, params }: HttpContextContract) {
|
||||
public async attachStudent({ response, request, params }: HttpContextContract) {
|
||||
try {
|
||||
const payload = await request.validate(AddCourseToUserValidator);
|
||||
const student = await this.User.findOrFail(payload.student_id);
|
||||
@ -225,7 +233,7 @@ export default class CoursesController {
|
||||
/**
|
||||
* Detach student from course
|
||||
*/
|
||||
async detachStudent({ response, request, params }: HttpContextContract) {
|
||||
public async detachStudent({ response, request, params }: HttpContextContract) {
|
||||
const payload = await request.validate(DelCourseFromUserValidator);
|
||||
const course = await this.Course.query().preload('students').where('id', params.id).firstOrFail();
|
||||
const candidate = course.students.find(student => student.id === payload.student_id);
|
||||
|
||||
@ -2,24 +2,32 @@ import { Exception } from '@adonisjs/core/build/standalone';
|
||||
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext';
|
||||
import Hash from '@ioc:Adonis/Core/Hash';
|
||||
import Logger from '@ioc:Adonis/Core/Logger';
|
||||
import ChangePasswordValidator from 'App/Validators/ChangePasswordValidator';
|
||||
|
||||
/**
|
||||
* Models
|
||||
*/
|
||||
import Contact from 'App/Models/Contact';
|
||||
|
||||
/**
|
||||
* Validators
|
||||
*/
|
||||
import ChangePasswordValidator from 'App/Validators/ChangePasswordValidator';
|
||||
import UpdateContactsValidator from 'App/Validators/UpdateContactsValidator';
|
||||
|
||||
export default class MeController {
|
||||
private readonly guard: 'api';
|
||||
|
||||
private readonly contact: typeof Contact;
|
||||
private readonly Contact: typeof Contact;
|
||||
|
||||
constructor() {
|
||||
this.contact = Contact;
|
||||
this.Contact = Contact;
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows user info of the access token resource owner.
|
||||
* GET /me
|
||||
*/
|
||||
public async index({ response, auth }: HttpContextContract) {
|
||||
public async show({ response, auth }: HttpContextContract) {
|
||||
const user = await auth.use(this.guard).authenticate();
|
||||
|
||||
await user.load('contacts');
|
||||
@ -73,7 +81,7 @@ export default class MeController {
|
||||
public async updateContacts({ request, response, auth }: HttpContextContract) {
|
||||
const payload = await request.validate(UpdateContactsValidator);
|
||||
const user = await auth.use(this.guard).authenticate();
|
||||
const contacts = await this.contact.findByOrFail('user_id', user.id);
|
||||
const contacts = await this.Contact.findByOrFail('user_id', user.id);
|
||||
|
||||
/**
|
||||
* Update contacts
|
||||
|
||||
@ -1,20 +1,28 @@
|
||||
import { Exception } from '@adonisjs/core/build/standalone';
|
||||
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext';
|
||||
|
||||
/**
|
||||
* Models
|
||||
*/
|
||||
import Role from 'App/Models/Role';
|
||||
import User from 'App/Models/User';
|
||||
|
||||
/**
|
||||
* Validators
|
||||
*/
|
||||
import AddRoleToUserValidator from 'App/Validators/AddRoleToUserValidator';
|
||||
import CreateUserValidator from 'App/Validators/CreateUserValidator';
|
||||
import DelRoleFromUserValidator from 'App/Validators/DelRoleFromUserValidator';
|
||||
import UpdateUserValidator from 'App/Validators/UpdateUserValidator';
|
||||
|
||||
export default class UsersController {
|
||||
private readonly user: typeof User;
|
||||
private readonly User: typeof User;
|
||||
|
||||
private readonly role: typeof Role;
|
||||
private readonly Role: typeof Role;
|
||||
|
||||
constructor() {
|
||||
this.user = User;
|
||||
this.role = Role;
|
||||
this.User = User;
|
||||
this.Role = Role;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -22,8 +30,8 @@ export default class UsersController {
|
||||
* GET /users
|
||||
*/
|
||||
|
||||
public async index({ response }: HttpContextContract) {
|
||||
const users = await this.user.query().preload('contacts').preload('roles');
|
||||
public async list({ response }: HttpContextContract) {
|
||||
const users = await this.User.query().preload('contacts').preload('roles');
|
||||
|
||||
return response.ok({
|
||||
message: 'Fetched all users.',
|
||||
@ -37,7 +45,7 @@ export default class UsersController {
|
||||
*/
|
||||
|
||||
public async show({ response, params }: HttpContextContract) {
|
||||
const user = await this.user.findOrFail(params.id);
|
||||
const user = await this.User.findOrFail(params.id);
|
||||
|
||||
await user.load('contacts');
|
||||
await user.load('roles');
|
||||
@ -56,7 +64,7 @@ export default class UsersController {
|
||||
public async create({ response, request }: HttpContextContract) {
|
||||
await request.validate(CreateUserValidator);
|
||||
|
||||
const user = await this.user.create({
|
||||
const user = await this.User.create({
|
||||
first_name: request.input('first_name'),
|
||||
last_name: request.input('last_name'),
|
||||
login: request.input('login'),
|
||||
@ -77,7 +85,7 @@ export default class UsersController {
|
||||
public async update({ request, response, params }: HttpContextContract) {
|
||||
await request.validate(UpdateUserValidator);
|
||||
|
||||
const user = await this.user.findOrFail(params.id);
|
||||
const user = await this.User.findOrFail(params.id);
|
||||
const input: Pick<User, 'first_name' | 'last_name' | 'login' | 'password'> = {
|
||||
first_name: request.input('first_name'),
|
||||
last_name: request.input('last_name'),
|
||||
@ -109,8 +117,8 @@ export default class UsersController {
|
||||
* DELETE /users/:id
|
||||
*/
|
||||
|
||||
public async destroy({ response, params }: HttpContextContract) {
|
||||
const user = await this.user.query().preload('contacts').preload('roles').where('id', params.id).firstOrFail();
|
||||
public async delete({ response, params }: HttpContextContract) {
|
||||
const user = await this.User.query().preload('contacts').preload('roles').where('id', params.id).firstOrFail();
|
||||
|
||||
await user.delete();
|
||||
|
||||
@ -128,10 +136,10 @@ export default class UsersController {
|
||||
await request.validate(AddRoleToUserValidator);
|
||||
|
||||
const input: string[] | undefined = request.input('roles');
|
||||
const user = await this.user.query().preload('roles').where('id', params.id).firstOrFail();
|
||||
const user = await this.User.query().preload('roles').where('id', params.id).firstOrFail();
|
||||
const roles = await this.findRolesBySlug(input);
|
||||
|
||||
await this.user.attachRoles(user, roles);
|
||||
await this.User.attachRoles(user, roles);
|
||||
|
||||
return response.ok({
|
||||
message: 'Roles attached',
|
||||
@ -147,10 +155,10 @@ export default class UsersController {
|
||||
await request.validate(DelRoleFromUserValidator);
|
||||
|
||||
const input: string[] | undefined = request.input('roles');
|
||||
const user = await this.user.query().preload('roles').where('id', params.id).firstOrFail();
|
||||
const user = await this.User.query().preload('roles').where('id', params.id).firstOrFail();
|
||||
const roles = await this.findRolesBySlug(input);
|
||||
|
||||
await this.user.detachRoles(user, roles);
|
||||
await this.User.detachRoles(user, roles);
|
||||
|
||||
return response.ok({
|
||||
message: 'Roles detached',
|
||||
@ -169,7 +177,7 @@ export default class UsersController {
|
||||
throw new Exception('Unable to find "roles" field in input.', 400, 'E_ROLES_FIELD_NOT_PROVIDED');
|
||||
}
|
||||
|
||||
const roles = await this.role.query().whereIn('slug', input);
|
||||
const roles = await this.Role.query().whereIn('slug', input);
|
||||
|
||||
input.forEach(val => {
|
||||
if (!roles.map(r => r.slug).includes(val)) {
|
||||
|
||||
8
routes/api.ts
Normal file
8
routes/api.ts
Normal file
@ -0,0 +1,8 @@
|
||||
/* eslint-disable global-require */
|
||||
import Route from '@ioc:Adonis/Core/Route';
|
||||
|
||||
Route.group(() => {
|
||||
require('./apis/v1/index');
|
||||
})
|
||||
.prefix('api')
|
||||
.as('api');
|
||||
6
routes/apis/v1/auth.ts
Normal file
6
routes/apis/v1/auth.ts
Normal file
@ -0,0 +1,6 @@
|
||||
import Route from '@ioc:Adonis/Core/Route';
|
||||
|
||||
Route.group(() => {
|
||||
Route.post('login', 'AuthController.login').as('auth.login');
|
||||
Route.post('logout', 'AuthController.logout').middleware('auth').as('auth.logout');
|
||||
}).prefix('auth');
|
||||
32
routes/apis/v1/courses.ts
Normal file
32
routes/apis/v1/courses.ts
Normal file
@ -0,0 +1,32 @@
|
||||
import Route from '@ioc:Adonis/Core/Route';
|
||||
|
||||
Route.group(() => {
|
||||
Route.get('/', 'CoursesController.list').middleware('role:admin,teacher,student').as('courses.list');
|
||||
Route.post('/', 'CoursesController.create').middleware('role:admin,teacher').as('courses.create');
|
||||
Route.get('/:id', 'CoursesController.show').middleware('role:admin,teacher,student').as('courses.show');
|
||||
Route.delete('/:id', 'CoursesController.delete').middleware('role:admin,teacher').as('courses.delete');
|
||||
Route.patch('/:id', 'CoursesController.update').middleware('role:admin,teacher').as('courses.update');
|
||||
Route.get('/:id/teacher', 'CoursesController.showTeacher')
|
||||
.middleware('role:admin,teacher,student')
|
||||
.as('courses.show-teacher');
|
||||
|
||||
Route.get('/:id/category', 'CoursesController.showCategory')
|
||||
.middleware('role:admin,teacher,student')
|
||||
.as('courses.show-category');
|
||||
|
||||
Route.get('/:id/lessons', 'CoursesController.showLessons')
|
||||
.middleware('role:admin,teacher,student')
|
||||
.as('courses.show-lessons');
|
||||
|
||||
Route.get('/:id/students', 'CoursesController.showStudents')
|
||||
.middleware('role:admin,teacher,student')
|
||||
.as('courses.show-students');
|
||||
|
||||
Route.post('/:id/attach-student', 'CoursesController.attachStudent')
|
||||
.middleware('role:admin,teacher')
|
||||
.as('courses.attach-student');
|
||||
|
||||
Route.delete('/:id/detach-student', 'CoursesController.detachStudent')
|
||||
.middleware('role:admin,teacher')
|
||||
.as('courses.detach-student');
|
||||
}).prefix('courses');
|
||||
40
routes/apis/v1/index.ts
Normal file
40
routes/apis/v1/index.ts
Normal file
@ -0,0 +1,40 @@
|
||||
/* eslint-disable global-require */
|
||||
import Route from '@ioc:Adonis/Core/Route';
|
||||
|
||||
Route.group(() => {
|
||||
Route.get('/', () => `Educt Backend API.`).as('index');
|
||||
|
||||
/**
|
||||
*
|
||||
* Auth module
|
||||
*
|
||||
*/
|
||||
require('./auth');
|
||||
|
||||
Route.group(() => {
|
||||
/**
|
||||
*
|
||||
* Users module
|
||||
*
|
||||
*/
|
||||
require('./users');
|
||||
|
||||
/**
|
||||
*
|
||||
* Me module
|
||||
*
|
||||
*/
|
||||
|
||||
require('./me');
|
||||
|
||||
/**
|
||||
*
|
||||
* Courses module
|
||||
*
|
||||
*/
|
||||
|
||||
require('./courses');
|
||||
}).middleware('auth');
|
||||
})
|
||||
.prefix('v1')
|
||||
.as('v1');
|
||||
11
routes/apis/v1/me.ts
Normal file
11
routes/apis/v1/me.ts
Normal file
@ -0,0 +1,11 @@
|
||||
import Route from '@ioc:Adonis/Core/Route';
|
||||
|
||||
Route.group(() => {
|
||||
Route.get('/', 'MeController.show').middleware('role:admin,teacher,student').as('me.show');
|
||||
Route.patch('/password', 'MeController.changePassword')
|
||||
.middleware('role:admin,teacher,student')
|
||||
.as('me.change-password');
|
||||
Route.put('/contacts', 'MeController.updateContacts')
|
||||
.middleware('role:admin,teacher,student')
|
||||
.as('me.update-contacts');
|
||||
}).prefix('me');
|
||||
11
routes/apis/v1/users.ts
Normal file
11
routes/apis/v1/users.ts
Normal file
@ -0,0 +1,11 @@
|
||||
import Route from '@ioc:Adonis/Core/Route';
|
||||
|
||||
Route.group(() => {
|
||||
Route.get('/', 'UsersController.list').middleware('role:admin,teacher,student').as('users.list');
|
||||
Route.post('/', 'UsersController.create').middleware('role:admin').as('users.create');
|
||||
Route.get('/:id', 'UsersController.show').middleware('role:admin,teacher,student').as('users.show');
|
||||
Route.patch('/:id', 'UsersController.update').middleware('role:admin').as('users.update');
|
||||
Route.delete('/:id', 'UsersController.delete').middleware('role:admin').as('users.delete');
|
||||
Route.post('/:id/attach-roles', 'UsersController.attachRoles').middleware('role:admin').as('users.attach-role');
|
||||
Route.delete('/:id/detach-roles', 'UsersController.detachRoles').middleware('role:admin').as('users.detach-role');
|
||||
}).prefix('users');
|
||||
26
routes/index.ts
Normal file
26
routes/index.ts
Normal file
@ -0,0 +1,26 @@
|
||||
/* eslint-disable global-require */
|
||||
import Route from '@ioc:Adonis/Core/Route';
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Routes
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This file is dedicated for defining HTTP routes. A single file is enough
|
||||
| for majority of projects, however you can define routes in different
|
||||
| files and just make sure to import them inside this file. For example
|
||||
|
|
||||
| Define routes in following two files
|
||||
| ├── start/routes/cart.ts
|
||||
| ├── start/routes/customer.ts
|
||||
|
|
||||
| and then import them inside `start/routes.ts` as follows
|
||||
|
|
||||
| import './routes/cart'
|
||||
| import './routes/customer'
|
||||
|
|
||||
*/
|
||||
|
||||
Route.group(() => {
|
||||
require('./api');
|
||||
});
|
||||
@ -1,89 +0,0 @@
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Routes
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This file is dedicated for defining HTTP routes. A single file is enough
|
||||
| for majority of projects, however you can define routes in different
|
||||
| files and just make sure to import them inside this file. For example
|
||||
|
|
||||
| Define routes in following two files
|
||||
| ├── start/routes/cart.ts
|
||||
| ├── start/routes/customer.ts
|
||||
|
|
||||
| and then import them inside `start/routes.ts` as follows
|
||||
|
|
||||
| import './routes/cart'
|
||||
| import './routes/customer'
|
||||
|
|
||||
*/
|
||||
|
||||
import Route from '@ioc:Adonis/Core/Route';
|
||||
|
||||
Route.get('/', () => `Educt Backend API.`);
|
||||
|
||||
Route.group(() => {
|
||||
/* Auth controller */
|
||||
Route.post('login', 'AuthController.login').as('login');
|
||||
Route.post('logout', 'AuthController.logout').middleware('auth').as('logout');
|
||||
|
||||
/* API */
|
||||
Route.group(() => {
|
||||
/**
|
||||
* Users controller
|
||||
*/
|
||||
Route.get('users', 'UsersController.index').middleware('role:admin,teacher,student').as('showAllUsers');
|
||||
Route.post('users', 'UsersController.create').middleware('role:admin').as('createUser');
|
||||
Route.get('users/:id', 'UsersController.show').middleware('role:admin,teacher,student').as('showUserById');
|
||||
Route.patch('users/:id', 'UsersController.update').middleware('role:admin').as('updateUser');
|
||||
Route.delete('users/:id', 'UsersController.destroy').middleware('role:admin').as('deleteUser');
|
||||
Route.post('users/:id/attach-roles', 'UsersController.attachRoles').middleware('role:admin').as('attachUserRole');
|
||||
Route.delete('users/:id/detach-roles', 'UsersController.detachRoles').middleware('role:admin').as('detachUserRole');
|
||||
|
||||
/**
|
||||
* Me controller
|
||||
*/
|
||||
Route.get('me', 'MeController.index').middleware('role:admin,teacher,student').as('showMe');
|
||||
Route.patch('me/password', 'MeController.changePassword')
|
||||
.middleware('role:admin,teacher,student')
|
||||
.as('changePassword');
|
||||
|
||||
Route.put('me/contacts', 'MeController.updateContacts')
|
||||
.middleware('role:admin,teacher,student')
|
||||
.as('updateContacts');
|
||||
|
||||
/**
|
||||
* Courses controller
|
||||
*/
|
||||
Route.get('courses', 'CoursesController.index').middleware('role:admin,teacher,student').as('showAllCourses');
|
||||
Route.post('courses', 'CoursesController.create').middleware('role:admin,teacher').as('createCourse');
|
||||
Route.get('courses/:id', 'CoursesController.show').middleware('role:admin,teacher,student').as('showCourseById');
|
||||
Route.delete('courses/:id', 'CoursesController.destroy').middleware('role:admin,teacher').as('deleteCourseById');
|
||||
Route.patch('courses/:id', 'CoursesController.update').middleware('role:admin,teacher').as('updateCourse');
|
||||
Route.get('courses/:id/teacher', 'CoursesController.showTeacher')
|
||||
.middleware('role:admin,teacher,student')
|
||||
.as('showCourseTeacher');
|
||||
|
||||
Route.get('courses/:id/category', 'CoursesController.showCategory')
|
||||
.middleware('role:admin,teacher,student')
|
||||
.as('showCourseCategory');
|
||||
|
||||
Route.get('courses/:id/lessons', 'CoursesController.showLessons')
|
||||
.middleware('role:admin,teacher,student')
|
||||
.as('showCourseLessons');
|
||||
|
||||
Route.get('courses/:id/students', 'CoursesController.showStudents')
|
||||
.middleware('role:admin,teacher,student')
|
||||
.as('showCourseStudents');
|
||||
|
||||
Route.post('courses/:id/attach-student', 'CoursesController.attachStudent')
|
||||
.middleware('role:admin,teacher')
|
||||
.as('attachUserCourse');
|
||||
|
||||
Route.delete('courses/:id/detach-student', 'CoursesController.detachStudent')
|
||||
.middleware('role:admin,teacher')
|
||||
.as('detachUserCourse');
|
||||
}).middleware('auth');
|
||||
})
|
||||
.prefix('/api/v1')
|
||||
.as('api');
|
||||
Loading…
x
Reference in New Issue
Block a user