Merge branch 'release/1.0.1'

This commit is contained in:
Sergey Yarkov 2021-12-08 18:26:28 +03:00
commit 4256ce618d
16 changed files with 254 additions and 201 deletions

View File

@ -4,6 +4,17 @@
- API deployment with Docker and Nginx web server.
## [1.0.1] - 2021-11-25
### Fix
- Creating materials for lesson
- Contacts updating
### Added
- Materials count for each lessons
## [1.0.0] - 2021-11-25
### Added

View File

@ -96,7 +96,7 @@ export default class MeController extends BaseController {
/**
* Update contacts of authenticated user
* PUT /me/contacts
* PATCH /me/contacts
*/
public async updateContacts(ctx: HttpContextContract) {
const payload = await ctx.request.validate(UpdateContactsValidator);

View File

@ -1,10 +1,21 @@
/* eslint-disable import/no-cycle */
/* eslint-disable no-param-reassign */
import { DateTime } from 'luxon';
import { nanoid } from 'nanoid';
import { BaseModel, beforeCreate, BelongsTo, belongsTo, column, HasOne, hasOne } from '@ioc:Adonis/Lucid/Orm';
import {
BaseModel,
beforeCreate,
BelongsTo,
belongsTo,
column,
hasMany,
HasMany,
HasOne,
hasOne,
} from '@ioc:Adonis/Lucid/Orm';
import ColorHelper from 'App/Helpers/ColorHelper';
import Course from './Course';
// eslint-disable-next-line import/no-cycle
import LessonMaterial from './LessonMaterial';
import LessonContent from './LessonContent';
import Color from './Color';
@ -45,6 +56,9 @@ export default class Lesson extends BaseModel {
})
public content: HasOne<typeof LessonContent>;
@hasMany(() => LessonMaterial, { foreignKey: 'lesson_id' })
public materials: HasMany<typeof LessonMaterial>;
@column.dateTime({ autoCreate: true })
public createdAt: DateTime;
@ -68,4 +82,13 @@ export default class Lesson extends BaseModel {
course.color_id = color.id;
}
}
/**
* Serialize the `$extras` object
*/
public serializeExtras() {
return {
materials_count: this.$extras.materials_count,
};
}
}

View File

@ -1,8 +1,7 @@
/* eslint-disable import/no-cycle */
import { BaseModel, BelongsTo, belongsTo, column, HasMany, hasMany } from '@ioc:Adonis/Lucid/Orm';
import { BaseModel, BelongsTo, belongsTo, column } from '@ioc:Adonis/Lucid/Orm';
import { DateTime } from 'luxon';
import Lesson from './Lesson';
import LessonMaterial from './LessonMaterial';
export default class LessonContent extends BaseModel {
@column({ isPrimary: true })
@ -14,9 +13,6 @@ export default class LessonContent extends BaseModel {
@column()
public video_url: string;
@hasMany(() => LessonMaterial, { foreignKey: 'lesson_content_id' })
public materials: HasMany<typeof LessonMaterial>;
@belongsTo(() => Lesson, { foreignKey: 'lesson_id' })
public lesson: BelongsTo<typeof Lesson>;

View File

@ -1,7 +1,7 @@
/* eslint-disable import/no-cycle */
import { BaseModel, BelongsTo, belongsTo, column } from '@ioc:Adonis/Lucid/Orm';
import { DateTime } from 'luxon';
// eslint-disable-next-line import/no-cycle
import LessonContent from './LessonContent';
import Lesson from './Lesson';
export default class LessonMaterial extends BaseModel {
@column({ isPrimary: true })
@ -20,12 +20,12 @@ export default class LessonMaterial extends BaseModel {
public ext: string;
@column()
public lesson_content_id: number;
public lesson_id: string;
@belongsTo(() => LessonContent, {
foreignKey: 'lesson_content_id',
@belongsTo(() => Lesson, {
foreignKey: 'lesson_id',
})
public content: BelongsTo<typeof LessonContent>;
public lesson: BelongsTo<typeof Lesson>;
@column.dateTime({ autoCreate: true })
public createdAt: DateTime;

View File

@ -62,10 +62,10 @@ export default class User extends BaseModel {
})
public likes: ManyToMany<typeof Course>;
@column.dateTime({ autoCreate: true, serializeAs: null })
@column.dateTime({ autoCreate: true })
public createdAt: DateTime;
@column.dateTime({ autoCreate: true, autoUpdate: true, serializeAs: null })
@column.dateTime({ autoCreate: true, autoUpdate: true })
public updatedAt: DateTime;
/**

View File

@ -63,12 +63,7 @@ export default class ContactRepository {
const contacts = await this.Contact.query().where('user_id', user.id).first();
if (contacts) {
contacts.phone_number = data.phone_number ?? null;
contacts.telegram_id = data.telegram_id?.substring(1) ?? null;
contacts.twitter_id = data.twitter_id?.substring(1) ?? null;
contacts.vk_id = data.vk_id ?? null;
await contacts.save();
await contacts.merge(data).save();
await user.load('contacts');
return contacts;

View File

@ -82,7 +82,7 @@ export default class CourseRepository {
.preload('teacher')
.preload('color')
.preload('category')
.preload('lessons', q => q.preload('color').orderBy('display_order', 'asc'))
.preload('lessons', q => q.preload('color').orderBy('display_order', 'asc').withCount('materials'))
.preload('students')
.where('id', id)
.first();

View File

@ -1,7 +1,8 @@
import Drive from '@ioc:Adonis/Core/Drive';
/**
* Models
*/
import Drive from '@ioc:Adonis/Core/Drive';
import Course from 'App/Models/Course';
import Lesson from 'App/Models/Lesson';
import LessonMaterial from 'App/Models/LessonMaterial';
@ -17,9 +18,12 @@ export default class LessonRepository {
private LessonMaterial: typeof LessonMaterial;
private Drive: typeof Drive;
constructor() {
this.Lesson = Lesson;
this.LessonMaterial = LessonMaterial;
this.Drive = Drive;
}
/**
@ -87,34 +91,54 @@ export default class LessonRepository {
await lesson.related('course').associate(course);
/**
* Create content and materials fields in database
* Create content
*/
const content = await lesson.related('content').create({ video_url: data.video_url });
await lesson.related('content').create({ video_url: data.video_url });
/**
* Create materials
*/
if (data.materials) {
await Promise.all(
/**
* Move each file to disk
*/
const files = await Promise.all(
data.materials.map(async file => {
/**
* Move each file to disk and then save in database
*/
await file.moveToDisk('materials');
if (file.state === 'moved') {
const url = await Drive.getUrl(`materials/${file.fileName}`);
await content.related('materials').create({
name: file.fileName,
clientName: file.clientName,
ext: file.extname,
url,
});
}
return file;
})
);
}
/**
* Create lesson material
*/
const materials = await Promise.all(
files.map(async file => {
if (file.state === 'moved' && file.fileName && file.extname) {
const url = await this.Drive.getUrl(`materials/${file.fileName}`);
const material = new LessonMaterial();
material.name = file.fileName;
material.clientName = file.clientName;
material.ext = file.extname;
material.url = url;
return material;
}
return null;
})
);
/**
* Save lesson materials to database
*/
await lesson.related('materials').createMany(materials.filter((l): l is LessonMaterial => l !== null));
}
/**
* Load data
*/
await lesson.load('content', q => q.preload('materials'));
await lesson.load(loader => loader.load('content').load('materials'));
return lesson;
}
@ -149,9 +173,21 @@ export default class LessonRepository {
* @returns Deleted lesson or null
*/
public async delete(id: string | number): Promise<Lesson | null> {
const lesson = await this.Lesson.query().where('id', id).first();
const lesson = await this.Lesson.query().where('id', id).preload('materials').preload('color').first();
if (lesson) {
/**
* Delete files from disk
*/
await Promise.all(
lesson.materials.map(async file => {
await this.Drive.delete(`materials/${file.name}`);
})
);
/**
* Delete lesson from database
*/
await lesson.delete();
return lesson;
}

View File

@ -101,12 +101,9 @@ export default class LessonService {
/**
* Allow user to view lesson material
*/
await material.load('content', q => q.preload('lesson'));
await material.load('lesson');
const {
content: { lesson },
} = material;
if (await ctx.bouncer.denies('viewLessonContent', lesson)) {
if (await ctx.bouncer.denies('viewLessonContent', material.lesson)) {
return {
success: false,
status: HttpStatusEnum.FORBIDDEN,
@ -254,9 +251,9 @@ export default class LessonService {
}
/**
* Load lesson content with materials
* Load lesson with materials
*/
await lesson.load('content', q => q.preload('materials'));
await lesson.load(loader => loader.load('content').load('materials'));
return {
success: true,

View File

@ -5,16 +5,16 @@ export default class UpdateContactsValidator {
constructor(protected ctx: HttpContextContract) {}
public schema = schema.create({
phone_number: schema.string.optional({}, [
phone_number: schema.string.nullableAndOptional({}, [
rules.mobile({
locales: ['ru-RU', 'en-US'],
strict: true,
}),
rules.unique({ table: 'contacts', column: 'phone_number' }),
]),
vk_id: schema.string.optional({}, [rules.regex(/^([a-zA-Z0-9_]){1,64}$/)]),
twitter_id: schema.string.optional({}, [rules.regex(/(^|[^@\w])@(\w{1,15})\b/)]),
telegram_id: schema.string.optional({}, [rules.regex(/(^|[^@\w])@(\w{1,64})\b/)]),
vk_id: schema.string.nullableAndOptional({}, [rules.regex(/^([a-zA-Z0-9_]){1,64}$/)]),
twitter_id: schema.string.nullableAndOptional({}, [rules.regex(/(^|[^@\w])@(\w{1,15})\b/)]),
telegram_id: schema.string.nullableAndOptional({}, [rules.regex(/(^|[^@\w])@(\w{1,64})\b/)]),
});
public messages = {

View File

@ -10,7 +10,7 @@ export default class LessonMaterials extends BaseSchema {
table.string('name').notNullable();
table.string('client_name').notNullable();
table.string('ext').notNullable();
table.integer('lesson_content_id').unsigned().references('lesson_contents.id').onDelete('CASCADE');
table.string('lesson_id', 21).unsigned().references('lessons.id').onDelete('CASCADE');
table.timestamp('created_at', { useTz: true });
table.timestamp('updated_at', { useTz: true });
});

278
package-lock.json generated
View File

@ -45,9 +45,9 @@
}
},
"slugify": {
"version": "1.6.1",
"resolved": "https://registry.npmjs.org/slugify/-/slugify-1.6.1.tgz",
"integrity": "sha512-5ofqMTbetNhxlzjYYLBaZFQd6oiTuSkQlyfPEFIMwgUABlZQ0hbk5xIV9Ydd5jghWeRoO7GkiJliUvTpLOjNRA=="
"version": "1.6.3",
"resolved": "https://registry.npmjs.org/slugify/-/slugify-1.6.3.tgz",
"integrity": "sha512-1MPyqnIhgiq+/0iDJyqSJHENdnH5MMIlgJIBxmkRMzTNKlS/QsN5dXsB+MdDq4E6w0g9jFA4XOTRkVDjDae/2w=="
}
}
},
@ -228,14 +228,14 @@
}
},
"luxon": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/luxon/-/luxon-2.0.2.tgz",
"integrity": "sha512-ZRioYLCgRHrtTORaZX1mx+jtxKtKuI5ZDvHNAmqpUzGqSrR+tL4FVLn/CUGMA3h0+AKD1MAxGI5GnCqR5txNqg=="
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/luxon/-/luxon-2.1.1.tgz",
"integrity": "sha512-6VQVNw7+kQu3hL1ZH5GyOhnk8uZm21xS7XJ/6vDZaFNcb62dpFDKcH8TI5NkoZOdMRxr7af7aYGrJlE/Wv0i1w=="
},
"slugify": {
"version": "1.6.1",
"resolved": "https://registry.npmjs.org/slugify/-/slugify-1.6.1.tgz",
"integrity": "sha512-5ofqMTbetNhxlzjYYLBaZFQd6oiTuSkQlyfPEFIMwgUABlZQ0hbk5xIV9Ydd5jghWeRoO7GkiJliUvTpLOjNRA=="
"version": "1.6.3",
"resolved": "https://registry.npmjs.org/slugify/-/slugify-1.6.3.tgz",
"integrity": "sha512-1MPyqnIhgiq+/0iDJyqSJHENdnH5MMIlgJIBxmkRMzTNKlS/QsN5dXsB+MdDq4E6w0g9jFA4XOTRkVDjDae/2w=="
}
}
},
@ -279,9 +279,9 @@
}
},
"slugify": {
"version": "1.6.1",
"resolved": "https://registry.npmjs.org/slugify/-/slugify-1.6.1.tgz",
"integrity": "sha512-5ofqMTbetNhxlzjYYLBaZFQd6oiTuSkQlyfPEFIMwgUABlZQ0hbk5xIV9Ydd5jghWeRoO7GkiJliUvTpLOjNRA=="
"version": "1.6.3",
"resolved": "https://registry.npmjs.org/slugify/-/slugify-1.6.3.tgz",
"integrity": "sha512-1MPyqnIhgiq+/0iDJyqSJHENdnH5MMIlgJIBxmkRMzTNKlS/QsN5dXsB+MdDq4E6w0g9jFA4XOTRkVDjDae/2w=="
}
}
},
@ -363,24 +363,24 @@
}
},
"@adonisjs/core": {
"version": "5.4.0",
"resolved": "https://registry.npmjs.org/@adonisjs/core/-/core-5.4.0.tgz",
"integrity": "sha512-HBeFOJu6wWXkNmHInIT6OQMtCTblT9MZK8l4tusNowKz41sE66vWIr9vE2CJBHEUfjo3MttBffVORP+RxMm1kQ==",
"version": "5.4.2",
"resolved": "https://registry.npmjs.org/@adonisjs/core/-/core-5.4.2.tgz",
"integrity": "sha512-8zPxWohIyNtJle4wHjbsGwrda7UFnJ0jVTgasANOCIveiKwbHKTbPfZqc3Oi+GLhzMhR8XLFh/3FGYtdEisisg==",
"requires": {
"@adonisjs/ace": "^11.0.4",
"@adonisjs/ace": "^11.0.5",
"@adonisjs/application": "^5.1.7",
"@adonisjs/bodyparser": "^8.0.1",
"@adonisjs/drive": "^2.0.7",
"@adonisjs/encryption": "^4.0.5",
"@adonisjs/events": "^7.1.2",
"@adonisjs/hash": "^7.0.8",
"@adonisjs/http-server": "^5.5.7",
"@adonisjs/validator": "^12.1.1",
"@adonisjs/http-server": "^5.6.0",
"@adonisjs/validator": "^12.2.0",
"@poppinss/cliui": "^2.2.5",
"@poppinss/manager": "^4.0.4",
"@poppinss/utils": "^3.3.0",
"@poppinss/utils": "^3.3.1",
"fs-extra": "^10.0.0",
"memfs": "^3.3.0",
"memfs": "^3.4.0",
"serve-static": "^1.14.1",
"stringify-attributes": "^2.0.0"
},
@ -399,19 +399,6 @@
"semver": "^7.3.5"
}
},
"@adonisjs/drive": {
"version": "2.0.7",
"resolved": "https://registry.npmjs.org/@adonisjs/drive/-/drive-2.0.7.tgz",
"integrity": "sha512-iQwQYyF/thj8ihJHUn/LBAAUYlOLAobAAnrzcQsmE8uFWRr0PRsqzpFaPF/S8UEnEyWQo4xGKXKJ8Zqzt4IOdw==",
"requires": {
"@poppinss/manager": "^4.0.4",
"@poppinss/utils": "^3.2.0",
"@types/fs-extra": "^9.0.12",
"etag": "^1.8.1",
"fs-extra": "^10.0.0",
"memfs": "^3.2.4"
}
},
"@adonisjs/logger": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/@adonisjs/logger/-/logger-4.1.1.tgz",
@ -447,14 +434,6 @@
"truncatise": "0.0.8"
}
},
"memfs": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/memfs/-/memfs-3.3.0.tgz",
"integrity": "sha512-BEE62uMfKOavX3iG7GYX43QJ+hAeeWnwIAuJ/R6q96jaMtiLzhsxHJC8B1L7fK7Pt/vXDRwb3SG/yBpNGDPqzg==",
"requires": {
"fs-monkey": "1.0.3"
}
},
"pino": {
"version": "6.13.3",
"resolved": "https://registry.npmjs.org/pino/-/pino-6.13.3.tgz",
@ -470,9 +449,9 @@
}
},
"slugify": {
"version": "1.6.1",
"resolved": "https://registry.npmjs.org/slugify/-/slugify-1.6.1.tgz",
"integrity": "sha512-5ofqMTbetNhxlzjYYLBaZFQd6oiTuSkQlyfPEFIMwgUABlZQ0hbk5xIV9Ydd5jghWeRoO7GkiJliUvTpLOjNRA=="
"version": "1.6.3",
"resolved": "https://registry.npmjs.org/slugify/-/slugify-1.6.3.tgz",
"integrity": "sha512-1MPyqnIhgiq+/0iDJyqSJHENdnH5MMIlgJIBxmkRMzTNKlS/QsN5dXsB+MdDq4E6w0g9jFA4XOTRkVDjDae/2w=="
},
"sonic-boom": {
"version": "1.4.1",
@ -523,9 +502,9 @@
}
},
"slugify": {
"version": "1.6.1",
"resolved": "https://registry.npmjs.org/slugify/-/slugify-1.6.1.tgz",
"integrity": "sha512-5ofqMTbetNhxlzjYYLBaZFQd6oiTuSkQlyfPEFIMwgUABlZQ0hbk5xIV9Ydd5jghWeRoO7GkiJliUvTpLOjNRA=="
"version": "1.6.3",
"resolved": "https://registry.npmjs.org/slugify/-/slugify-1.6.3.tgz",
"integrity": "sha512-1MPyqnIhgiq+/0iDJyqSJHENdnH5MMIlgJIBxmkRMzTNKlS/QsN5dXsB+MdDq4E6w0g9jFA4XOTRkVDjDae/2w=="
}
}
},
@ -562,9 +541,9 @@
}
},
"slugify": {
"version": "1.6.1",
"resolved": "https://registry.npmjs.org/slugify/-/slugify-1.6.1.tgz",
"integrity": "sha512-5ofqMTbetNhxlzjYYLBaZFQd6oiTuSkQlyfPEFIMwgUABlZQ0hbk5xIV9Ydd5jghWeRoO7GkiJliUvTpLOjNRA=="
"version": "1.6.3",
"resolved": "https://registry.npmjs.org/slugify/-/slugify-1.6.3.tgz",
"integrity": "sha512-1MPyqnIhgiq+/0iDJyqSJHENdnH5MMIlgJIBxmkRMzTNKlS/QsN5dXsB+MdDq4E6w0g9jFA4XOTRkVDjDae/2w=="
}
}
},
@ -689,16 +668,16 @@
}
},
"slugify": {
"version": "1.6.1",
"resolved": "https://registry.npmjs.org/slugify/-/slugify-1.6.1.tgz",
"integrity": "sha512-5ofqMTbetNhxlzjYYLBaZFQd6oiTuSkQlyfPEFIMwgUABlZQ0hbk5xIV9Ydd5jghWeRoO7GkiJliUvTpLOjNRA=="
"version": "1.6.3",
"resolved": "https://registry.npmjs.org/slugify/-/slugify-1.6.3.tgz",
"integrity": "sha512-1MPyqnIhgiq+/0iDJyqSJHENdnH5MMIlgJIBxmkRMzTNKlS/QsN5dXsB+MdDq4E6w0g9jFA4XOTRkVDjDae/2w=="
}
}
},
"@adonisjs/http-server": {
"version": "5.5.7",
"resolved": "https://registry.npmjs.org/@adonisjs/http-server/-/http-server-5.5.7.tgz",
"integrity": "sha512-p3V00t/X8U7bSjgjJ73ReC5VNifXVWRuBUA6HsdAf3lOzKtuqFznjjA9y8qhO3kITD8x11bPzi6MZptkcP6ybQ==",
"version": "5.6.0",
"resolved": "https://registry.npmjs.org/@adonisjs/http-server/-/http-server-5.6.0.tgz",
"integrity": "sha512-XAy3nqId/MkmzsaEocnGWnbjSra2hVjwV/979+yOfEgmK/4vqH3rpEJjZ8PcbeG0Y7nwgF7iY/wO5KFA2lEjDw==",
"requires": {
"@poppinss/matchit": "^3.1.2",
"@poppinss/utils": "^3.1.5",
@ -749,9 +728,9 @@
}
},
"slugify": {
"version": "1.6.1",
"resolved": "https://registry.npmjs.org/slugify/-/slugify-1.6.1.tgz",
"integrity": "sha512-5ofqMTbetNhxlzjYYLBaZFQd6oiTuSkQlyfPEFIMwgUABlZQ0hbk5xIV9Ydd5jghWeRoO7GkiJliUvTpLOjNRA=="
"version": "1.6.3",
"resolved": "https://registry.npmjs.org/slugify/-/slugify-1.6.3.tgz",
"integrity": "sha512-1MPyqnIhgiq+/0iDJyqSJHENdnH5MMIlgJIBxmkRMzTNKlS/QsN5dXsB+MdDq4E6w0g9jFA4XOTRkVDjDae/2w=="
}
}
},
@ -806,9 +785,9 @@
}
},
"@adonisjs/lucid": {
"version": "16.2.1",
"resolved": "https://registry.npmjs.org/@adonisjs/lucid/-/lucid-16.2.1.tgz",
"integrity": "sha512-1UAPyB3j/JkGHMT5G3YkkoCdVSaTHtm1Mn3HwSzvkAQ7d7Ffx88SYZFwpTdtT8oDfxxHunzZuTaWG0CmoUixcA==",
"version": "16.3.2",
"resolved": "https://registry.npmjs.org/@adonisjs/lucid/-/lucid-16.3.2.tgz",
"integrity": "sha512-RFY3wVGJ04KlhkvLxsNkkLgDa8v1OpVB6F6D2vwW+jHKpAOSvYc/fzvQE6RoCpdP7vfn3VcO5iikDqtXopM6KQ==",
"requires": {
"@poppinss/hooks": "^3.0.5",
"@poppinss/utils": "^3.2.1",
@ -850,14 +829,14 @@
}
},
"luxon": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/luxon/-/luxon-2.0.2.tgz",
"integrity": "sha512-ZRioYLCgRHrtTORaZX1mx+jtxKtKuI5ZDvHNAmqpUzGqSrR+tL4FVLn/CUGMA3h0+AKD1MAxGI5GnCqR5txNqg=="
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/luxon/-/luxon-2.1.1.tgz",
"integrity": "sha512-6VQVNw7+kQu3hL1ZH5GyOhnk8uZm21xS7XJ/6vDZaFNcb62dpFDKcH8TI5NkoZOdMRxr7af7aYGrJlE/Wv0i1w=="
},
"slugify": {
"version": "1.6.1",
"resolved": "https://registry.npmjs.org/slugify/-/slugify-1.6.1.tgz",
"integrity": "sha512-5ofqMTbetNhxlzjYYLBaZFQd6oiTuSkQlyfPEFIMwgUABlZQ0hbk5xIV9Ydd5jghWeRoO7GkiJliUvTpLOjNRA=="
"version": "1.6.3",
"resolved": "https://registry.npmjs.org/slugify/-/slugify-1.6.3.tgz",
"integrity": "sha512-1MPyqnIhgiq+/0iDJyqSJHENdnH5MMIlgJIBxmkRMzTNKlS/QsN5dXsB+MdDq4E6w0g9jFA4XOTRkVDjDae/2w=="
}
}
},
@ -1098,17 +1077,17 @@
}
},
"@adonisjs/validator": {
"version": "12.1.1",
"resolved": "https://registry.npmjs.org/@adonisjs/validator/-/validator-12.1.1.tgz",
"integrity": "sha512-vqp3NAuJd1L1DX0AVL7T5jSmpzmjjbKAPR9hj+2uQT0oclAWEP3zIGvpmab/QFcF8y7njzjiYY1Q2CsP3dptUg==",
"version": "12.2.0",
"resolved": "https://registry.npmjs.org/@adonisjs/validator/-/validator-12.2.0.tgz",
"integrity": "sha512-dNb/x7tgE4pzwrrxd/gNhxv2mghxoWCIl8/ThdJNAAUGkXQY7V697ny29diyxmF/2yH2xu1d0fTA6vDw179z5g==",
"requires": {
"@poppinss/utils": "^3.3.0",
"@types/luxon": "^2.0.5",
"@types/validator": "^13.6.3",
"luxon": "^2.0.1",
"@poppinss/utils": "^3.3.1",
"@types/luxon": "^2.0.7",
"@types/validator": "^13.7.0",
"luxon": "^2.1.1",
"normalize-url": "^6.1.0",
"tmp-cache": "^1.1.0",
"validator": "^13.6.0"
"validator": "^13.7.0"
},
"dependencies": {
"@poppinss/utils": {
@ -1136,14 +1115,19 @@
}
},
"luxon": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/luxon/-/luxon-2.0.2.tgz",
"integrity": "sha512-ZRioYLCgRHrtTORaZX1mx+jtxKtKuI5ZDvHNAmqpUzGqSrR+tL4FVLn/CUGMA3h0+AKD1MAxGI5GnCqR5txNqg=="
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/luxon/-/luxon-2.1.1.tgz",
"integrity": "sha512-6VQVNw7+kQu3hL1ZH5GyOhnk8uZm21xS7XJ/6vDZaFNcb62dpFDKcH8TI5NkoZOdMRxr7af7aYGrJlE/Wv0i1w=="
},
"slugify": {
"version": "1.6.1",
"resolved": "https://registry.npmjs.org/slugify/-/slugify-1.6.1.tgz",
"integrity": "sha512-5ofqMTbetNhxlzjYYLBaZFQd6oiTuSkQlyfPEFIMwgUABlZQ0hbk5xIV9Ydd5jghWeRoO7GkiJliUvTpLOjNRA=="
"version": "1.6.3",
"resolved": "https://registry.npmjs.org/slugify/-/slugify-1.6.3.tgz",
"integrity": "sha512-1MPyqnIhgiq+/0iDJyqSJHENdnH5MMIlgJIBxmkRMzTNKlS/QsN5dXsB+MdDq4E6w0g9jFA4XOTRkVDjDae/2w=="
},
"validator": {
"version": "13.7.0",
"resolved": "https://registry.npmjs.org/validator/-/validator-13.7.0.tgz",
"integrity": "sha512-nYXQLCBkpJ8X6ltALua9dRrZDHVYxjJ1wgskNt1lH9fzGjs3tgojGSCBjmEPwkWS1y29+DrizMTW19Pr9uB2nw=="
}
}
},
@ -1445,25 +1429,6 @@
"http-errors": "~1.8.0",
"safe-buffer": "5.2.1",
"uid-safe": "2.1.5"
},
"dependencies": {
"http-errors": {
"version": "1.8.0",
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.0.tgz",
"integrity": "sha512-4I8r0C5JDhT5VkvI47QktDW75rNlGVsUf/8hzjCC/wkWI/jdTRmBb9aI7erSG82r1bjKY3F6k28WnsVxB1C73A==",
"requires": {
"depd": "~1.1.2",
"inherits": "2.0.4",
"setprototypeof": "1.2.0",
"statuses": ">= 1.5.0 < 2",
"toidentifier": "1.0.0"
}
},
"setprototypeof": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
"integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="
}
}
},
"@poppinss/prompts": {
@ -1539,9 +1504,9 @@
"integrity": "sha512-uCx6mP3UY5SIO14XlspxsGjgaemrxpssJI0Ol+GfhxtcKpv9pgRZYsS4eeKeHVLje6Qtc8lGszuBI461+gVZBA=="
},
"@types/fs-extra": {
"version": "9.0.12",
"resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-9.0.12.tgz",
"integrity": "sha512-I+bsBr67CurCGnSenZZ7v94gd3tc3+Aj2taxMT4yu4ABLuOgOjeFxX3dokG24ztSRg5tnT00sL8BszO7gSMoIw==",
"version": "9.0.13",
"resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-9.0.13.tgz",
"integrity": "sha512-nEnwB++1u5lVDM2UI4c1+5R+FYaKfaAzS4OococimjVm3nQw3TuzH5UNsocrcTBbhnerblyHj4A49qXbIiZdpA==",
"requires": {
"@types/node": "*"
}
@ -1595,9 +1560,9 @@
}
},
"@types/luxon": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/@types/luxon/-/luxon-2.0.5.tgz",
"integrity": "sha512-GKrG5v16BOs9XGpouu33hOkAFaiSDi3ZaDXG9F2yAoyzHRBtksZnI60VWY5aM/yAENCccBejrxw8jDY+9OVlxw=="
"version": "2.0.7",
"resolved": "https://registry.npmjs.org/@types/luxon/-/luxon-2.0.7.tgz",
"integrity": "sha512-AxiYycfO+/M4VIH0ribSr2iPFC+APewpJIaQSydwVnzorK3mjSFXkA3HmhQidGx44MpwaatFyEkbW/WD4zdDaQ=="
},
"@types/minimatch": {
"version": "3.0.5",
@ -1652,9 +1617,9 @@
"dev": true
},
"@types/validator": {
"version": "13.6.5",
"resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.6.5.tgz",
"integrity": "sha512-ilpDKpjjq/w/IyyTuQ38mABdaEzTzTugPyU7DlMCMKd8MMYngnPKhA2TgdO1MfEDED9KVV7uSOL1fDkgwJp/wg=="
"version": "13.7.0",
"resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.7.0.tgz",
"integrity": "sha512-+jBxVvXVuggZOrm04NR8z+5+bgoW4VZyLzUO+hmPPW1mVFL/HaitLAkizfv4yg9TbG8lkfHWVMQ11yDqrVVCzA=="
},
"@typescript-eslint/eslint-plugin": {
"version": "4.30.0",
@ -2662,9 +2627,9 @@
"integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg=="
},
"colorette": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.1.tgz",
"integrity": "sha512-puCDz0CzydiSYOrnXpz/PKd69zRrribezjtE9yd4zvytoRc8+RY/KJPvtPFKZS3E3wP6neGyMe0vOTlHO5L3Pw=="
"version": "2.0.16",
"resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.16.tgz",
"integrity": "sha512-hUewv7oMjCp+wkBv5Rm0v87eJhq4woh5rSR+42YSQJKecCqgIqNkZ6lAlQms/BwHPJA5NKMRlpxPRv0n8HQW6g=="
},
"colors": {
"version": "1.4.0",
@ -4400,15 +4365,15 @@
"integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ=="
},
"http-errors": {
"version": "1.7.3",
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.3.tgz",
"integrity": "sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw==",
"version": "1.8.1",
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz",
"integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==",
"requires": {
"depd": "~1.1.2",
"inherits": "2.0.4",
"setprototypeof": "1.1.1",
"setprototypeof": "1.2.0",
"statuses": ">= 1.5.0 < 2",
"toidentifier": "1.0.0"
"toidentifier": "1.0.1"
}
},
"http2-wrapper": {
@ -4903,11 +4868,11 @@
"integrity": "sha512-8QADVssbrFjivHWQU7KkMgptGTl6WAcSdlbBPY4uNF+mWr6DGcKrvY2w4FQJoXch7+fKMjj0dRrL75vk3k23OA=="
},
"knex": {
"version": "0.95.11",
"resolved": "https://registry.npmjs.org/knex/-/knex-0.95.11.tgz",
"integrity": "sha512-grDetD91O8VoQVCFqeWTgkzdq5406W6rggF/lK1hHuwzmjDs/0m9KxyncGdZbklTi7aUgHvw3+Cfy4x7FvpdaQ==",
"version": "0.95.14",
"resolved": "https://registry.npmjs.org/knex/-/knex-0.95.14.tgz",
"integrity": "sha512-j4qLjWySrC/JRRVtOpoR2LcS1yBOsd7Krc6mEukPvmTDX/w11pD52Pq9FYR56/kLXGeAV8jFdWBjsZFi1mscWg==",
"requires": {
"colorette": "1.2.1",
"colorette": "2.0.16",
"commander": "^7.1.0",
"debug": "4.3.2",
"escalade": "^3.1.1",
@ -5162,9 +5127,9 @@
}
},
"memfs": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/memfs/-/memfs-3.3.0.tgz",
"integrity": "sha512-BEE62uMfKOavX3iG7GYX43QJ+hAeeWnwIAuJ/R6q96jaMtiLzhsxHJC8B1L7fK7Pt/vXDRwb3SG/yBpNGDPqzg==",
"version": "3.4.0",
"resolved": "https://registry.npmjs.org/memfs/-/memfs-3.4.0.tgz",
"integrity": "sha512-o/RfP0J1d03YwsAxyHxAYs2kyJp55AFkMazlFAZFR2I2IXkxiUTXRabJ6RmNNCQ83LAD2jy52Khj0m3OffpNdA==",
"requires": {
"fs-monkey": "1.0.3"
}
@ -6349,9 +6314,9 @@
"integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc="
},
"qs": {
"version": "6.10.1",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.10.1.tgz",
"integrity": "sha512-M528Hph6wsSVOBiYUnGf+K/7w0hNshs/duGsNXPUCLH5XAqjEtiPGwNONLV0tBH8NoGb0mvD5JubnUTrujKDTg==",
"version": "6.10.2",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.10.2.tgz",
"integrity": "sha512-mSIdjzqznWgfd4pMii7sHtaYF8rx8861hBO80SraY5GT0XQibWZWJSid0avzHGkDIZLImux2S5mXO0Hfct2QCw==",
"requires": {
"side-channel": "^1.0.4"
}
@ -6383,14 +6348,21 @@
"integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg=="
},
"raw-body": {
"version": "2.4.1",
"resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.1.tgz",
"integrity": "sha512-9WmIKF6mkvA0SLmA2Knm9+qj89e+j1zqgyn8aXGd7+nAduPoqgI9lO57SAZNn/Byzo5P7JhXTyg9PzaJbH73bA==",
"version": "2.4.2",
"resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.2.tgz",
"integrity": "sha512-RPMAFUJP19WIet/99ngh6Iv8fzAbqum4Li7AD6DtGaW2RpMB/11xDoalPiJMTbu6I3hkbMVkATvZrqb9EEqeeQ==",
"requires": {
"bytes": "3.1.0",
"http-errors": "1.7.3",
"bytes": "3.1.1",
"http-errors": "1.8.1",
"iconv-lite": "0.4.24",
"unpipe": "1.0.0"
},
"dependencies": {
"bytes": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.1.tgz",
"integrity": "sha512-dWe4nWO/ruEOY7HkUJ5gFt1DCFV9zPRoJr8pV0/ASQermOZjtq8jMjOprC0Kd10GLN+l7xaUPvxzJFWtxGu8Fg=="
}
}
},
"rc": {
@ -6736,10 +6708,32 @@
}
}
},
"http-errors": {
"version": "1.7.3",
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.3.tgz",
"integrity": "sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw==",
"requires": {
"depd": "~1.1.2",
"inherits": "2.0.4",
"setprototypeof": "1.1.1",
"statuses": ">= 1.5.0 < 2",
"toidentifier": "1.0.0"
}
},
"ms": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
"integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg=="
},
"setprototypeof": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz",
"integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw=="
},
"toidentifier": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz",
"integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw=="
}
}
},
@ -6798,9 +6792,9 @@
}
},
"setprototypeof": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz",
"integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw=="
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
"integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="
},
"shebang-command": {
"version": "2.0.0",
@ -7306,9 +7300,9 @@
}
},
"tarn": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/tarn/-/tarn-3.0.1.tgz",
"integrity": "sha512-6usSlV9KyHsspvwu2duKH+FMUhqJnAh6J5J/4MITl8s94iSUQTLkJggdiewKv4RyARQccnigV48Z+khiuVZDJw=="
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/tarn/-/tarn-3.0.2.tgz",
"integrity": "sha512-51LAVKUSZSVfI05vjPESNc5vwqqZpbXCsU+/+wxlOrUjk2SnFTt97v9ZgQrD4YmxYW1Px6w2KjaDitCfkvgxMQ=="
},
"term-size": {
"version": "2.2.1",
@ -7373,9 +7367,9 @@
}
},
"toidentifier": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz",
"integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw=="
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
"integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA=="
},
"token-types": {
"version": "4.1.1",

View File

@ -1,6 +1,6 @@
{
"name": "server",
"version": "1.0.0",
"version": "1.0.1",
"private": true,
"scripts": {
"build": "node ace build --production",
@ -35,9 +35,9 @@
"@adonisjs/attachment-lite": "^1.0.1",
"@adonisjs/auth": "^8.0.10",
"@adonisjs/bouncer": "^2.2.5",
"@adonisjs/core": "^5.4.0",
"@adonisjs/core": "^5.4.2",
"@adonisjs/drive": "^2.0.7",
"@adonisjs/lucid": "^16.2.1",
"@adonisjs/lucid": "^16.3.2",
"@adonisjs/mail": "^7.2.4",
"@adonisjs/redis": "^7.0.9",
"@adonisjs/repl": "^3.1.7",

View File

@ -53,8 +53,9 @@ Route.group(() => {
*
* Images module
*
* This module is not necessary yet
*/
require('./images');
// require('./images');
/**
*

View File

@ -11,7 +11,7 @@ Route.group(() => {
Route.patch('/password', 'Api/v1/MeController.changePassword')
.middleware('role:admin,teacher,student')
.as('me.change-password');
Route.put('/contacts', 'Api/v1/MeController.updateContacts')
Route.patch('/contacts', 'Api/v1/MeController.updateContacts')
.middleware('role:admin,teacher,student')
.as('me.update-contacts');
}).prefix('me');