- additional functionality for DatasetController.ts
All checks were successful
CI Pipeline / japa-tests (push) Successful in 47s
All checks were successful
CI Pipeline / japa-tests (push) Successful in 47s
- additional validation rules like 'uniqueArray' - additional Lucid models like BaseModel.ts for filling attributes, Title.ts, Description.ts - npm updates for @adonisjs/core
This commit is contained in:
parent
c4f4eff0d9
commit
e0ff71b117
|
@ -1,17 +1,17 @@
|
||||||
import type { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
|
import type { HttpContextContract } from '@ioc:Adonis/Core/HttpContext';
|
||||||
|
|
||||||
export default class HomeController {
|
export default class HomeController {
|
||||||
public async index({}: HttpContextContract) {}
|
public async index({}: HttpContextContract) {}
|
||||||
|
|
||||||
public async create({}: HttpContextContract) {}
|
public async create({}: HttpContextContract) {}
|
||||||
|
|
||||||
public async store({}: HttpContextContract) {}
|
public async store({}: HttpContextContract) {}
|
||||||
|
|
||||||
public async show({}: HttpContextContract) {}
|
public async show({}: HttpContextContract) {}
|
||||||
|
|
||||||
public async edit({}: HttpContextContract) {}
|
public async edit({}: HttpContextContract) {}
|
||||||
|
|
||||||
public async update({}: HttpContextContract) {}
|
public async update({}: HttpContextContract) {}
|
||||||
|
|
||||||
public async destroy({}: HttpContextContract) {}
|
public async destroy({}: HttpContextContract) {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,197 +8,207 @@ import { RenderResponse } from '@ioc:EidelLev/Inertia';
|
||||||
// import { schema, rules } from '@ioc:Adonis/Core/Validator';
|
// import { schema, rules } from '@ioc:Adonis/Core/Validator';
|
||||||
|
|
||||||
export default class UsersController {
|
export default class UsersController {
|
||||||
public async index({ auth, request, inertia }: HttpContextContract) {
|
public async index({ auth, request, inertia }: HttpContextContract) {
|
||||||
const page = request.input('page', 1);
|
const page = request.input('page', 1);
|
||||||
// const limit = 10
|
// const limit = 10
|
||||||
|
|
||||||
let users: ModelQueryBuilderContract<typeof User, User> = User.query();
|
let users: ModelQueryBuilderContract<typeof User, User> = User.query();
|
||||||
|
|
||||||
if (request.input('search')) {
|
if (request.input('search')) {
|
||||||
// users = users.whereRaw('name like %?%', [request.input('search')])
|
// users = users.whereRaw('name like %?%', [request.input('search')])
|
||||||
const searchTerm = request.input('search');
|
const searchTerm = request.input('search');
|
||||||
users.where('login', 'ilike', `%${searchTerm}%`);
|
users.where('login', 'ilike', `%${searchTerm}%`);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (request.input('sort')) {
|
if (request.input('sort')) {
|
||||||
type SortOrder = 'asc' | 'desc' | undefined;
|
type SortOrder = 'asc' | 'desc' | undefined;
|
||||||
let attribute = request.input('sort');
|
let attribute = request.input('sort');
|
||||||
let sort_order: SortOrder = 'asc';
|
let sort_order: SortOrder = 'asc';
|
||||||
|
|
||||||
// if (strncmp($attribute, '-', 1) === 0) {
|
// if (strncmp($attribute, '-', 1) === 0) {
|
||||||
if (attribute.substr(0, 1) == '-') {
|
if (attribute.substr(0, 1) == '-') {
|
||||||
sort_order = 'desc';
|
sort_order = 'desc';
|
||||||
// attribute = substr(attribute, 1);
|
// attribute = substr(attribute, 1);
|
||||||
attribute = attribute.substr(1);
|
attribute = attribute.substr(1);
|
||||||
}
|
}
|
||||||
// $users->orderBy($attribute, $sort_order);
|
// $users->orderBy($attribute, $sort_order);
|
||||||
users.orderBy(attribute, sort_order);
|
users.orderBy(attribute, sort_order);
|
||||||
} else {
|
} else {
|
||||||
// users.orderBy('created_at', 'desc');
|
// users.orderBy('created_at', 'desc');
|
||||||
users.orderBy('id', 'asc');
|
users.orderBy('id', 'asc');
|
||||||
}
|
}
|
||||||
|
|
||||||
// const users = await User.query().orderBy('login').paginate(page, limit);
|
// const users = await User.query().orderBy('login').paginate(page, limit);
|
||||||
|
|
||||||
let usersResult = await users // User.query()
|
let usersResult = await users // User.query()
|
||||||
// .orderBy('login')
|
// .orderBy('login')
|
||||||
// .filter(qs)
|
// .filter(qs)
|
||||||
// .preload('focusInterests')
|
// .preload('focusInterests')
|
||||||
// .preload('role')
|
// .preload('role')
|
||||||
.paginate(page, 5);
|
.paginate(page, 5);
|
||||||
|
|
||||||
// var test = request.all();
|
// var test = request.all();
|
||||||
|
|
||||||
return inertia.render('Admin/User/Index', {
|
return inertia.render('Admin/User/Index', {
|
||||||
// testing: 'this is a test',
|
// testing: 'this is a test',
|
||||||
users: usersResult.toJSON(),
|
users: usersResult.toJSON(),
|
||||||
filters: request.all(),
|
filters: request.all(),
|
||||||
can: {
|
can: {
|
||||||
create: await auth.user?.can(['user-create']),
|
create: await auth.user?.can(['user-create']),
|
||||||
edit: await auth.user?.can(['user-edit']),
|
edit: await auth.user?.can(['user-edit']),
|
||||||
delete: await auth.user?.can(['user-delete']),
|
delete: await auth.user?.can(['user-delete']),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public async create({ inertia }: HttpContextContract) {
|
public async create({ inertia }: HttpContextContract) {
|
||||||
// let rolesPluck = {};
|
// let rolesPluck = {};
|
||||||
// (await Role.query().select('id', 'name')).forEach((user) => {
|
// (await Role.query().select('id', 'name')).forEach((user) => {
|
||||||
// rolesPluck[user.id] = user.name;
|
// rolesPluck[user.id] = user.name;
|
||||||
// });
|
// });
|
||||||
const roles = await Role.query().select('id', 'name').pluck('name', 'id');
|
const roles = await Role.query().select('id', 'name').pluck('name', 'id');
|
||||||
|
|
||||||
return inertia.render('Admin/User/Create', {
|
return inertia.render('Admin/User/Create', {
|
||||||
roles: roles,
|
roles: roles,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public async store({ request, response, session }: HttpContextContract) {
|
public async store({ request, response, session }: HttpContextContract) {
|
||||||
// node ace make:validator CreateUser
|
// node ace make:validator CreateUser
|
||||||
try {
|
try {
|
||||||
// Step 2 - Validate request body against the schema
|
// Step 2 - Validate request body against the schema
|
||||||
await request.validate(CreateUserValidator);
|
await request.validate(CreateUserValidator);
|
||||||
// console.log({ payload });
|
// console.log({ payload });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// Step 3 - Handle errors
|
// Step 3 - Handle errors
|
||||||
// return response.badRequest(error.messages);
|
// return response.badRequest(error.messages);
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
const input = request.only(['login', 'email', 'password']);
|
const input = request.only(['login', 'email', 'password']);
|
||||||
const user = await User.create(input);
|
const user = await User.create(input);
|
||||||
if (request.input('roles')) {
|
if (request.input('roles')) {
|
||||||
const roles: Array<number> = request.input('roles');
|
const roles: Array<number> = request.input('roles');
|
||||||
await user.related('roles').attach(roles);
|
await user.related('roles').attach(roles);
|
||||||
}
|
}
|
||||||
|
|
||||||
session.flash('message', 'User has been created successfully');
|
session.flash('message', 'User has been created successfully');
|
||||||
return response.redirect().toRoute('user.index');
|
return response.redirect().toRoute('user.index');
|
||||||
}
|
}
|
||||||
|
|
||||||
public async show({ request, inertia }: HttpContextContract) {
|
public async show({ request, inertia }: HttpContextContract) {
|
||||||
const id = request.param('id');
|
const id = request.param('id');
|
||||||
const user = await User.query().where('id', id).firstOrFail();
|
const user = await User.query().where('id', id).firstOrFail();
|
||||||
|
|
||||||
const roles = await Role.query().pluck('name', 'id');
|
const roles = await Role.query().pluck('name', 'id');
|
||||||
// const userHasRoles = user.roles;
|
// const userHasRoles = user.roles;
|
||||||
const userRoles = await user.related('roles').query().orderBy('name').pluck('id');
|
const userRoles = await user.related('roles').query().orderBy('name').pluck('id');
|
||||||
|
|
||||||
return inertia.render('Admin/User/Show', {
|
return inertia.render('Admin/User/Show', {
|
||||||
roles: roles,
|
roles: roles,
|
||||||
user: user,
|
user: user,
|
||||||
userHasRoles: userRoles,
|
userHasRoles: userRoles,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public async edit({ request, inertia }: HttpContextContract) {
|
public async edit({ request, inertia }: HttpContextContract) {
|
||||||
const id = request.param('id');
|
const id = request.param('id');
|
||||||
const user = await User.query().where('id', id).firstOrFail();
|
const user = await User.query().where('id', id).firstOrFail();
|
||||||
|
|
||||||
const roles = await Role.query().pluck('name', 'id');
|
const roles = await Role.query().pluck('name', 'id');
|
||||||
// const userHasRoles = user.roles;
|
// const userHasRoles = user.roles;
|
||||||
const userHasRoles = await user.related('roles').query().orderBy('name').pluck('id');
|
const userHasRoles = await user.related('roles').query().orderBy('name').pluck('id');
|
||||||
// let test = Object.keys(userHasRoles).map((key) => userHasRoles[key]);
|
// let test = Object.keys(userHasRoles).map((key) => userHasRoles[key]);
|
||||||
return inertia.render('Admin/User/Edit', {
|
return inertia.render('Admin/User/Edit', {
|
||||||
roles: roles,
|
roles: roles,
|
||||||
user: user,
|
user: user,
|
||||||
userHasRoles: Object.keys(userHasRoles).map((key) => userHasRoles[key]), //convert object to array with role ids
|
userHasRoles: Object.keys(userHasRoles).map((key) => userHasRoles[key]), //convert object to array with role ids
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public async update({ request, response, session }: HttpContextContract) {
|
public async update({ request, response, session }: HttpContextContract) {
|
||||||
// node ace make:validator UpdateUser
|
// node ace make:validator UpdateUser
|
||||||
const id = request.param('id');
|
const id = request.param('id');
|
||||||
const user = await User.query().where('id', id).firstOrFail();
|
const user = await User.query().where('id', id).firstOrFail();
|
||||||
|
|
||||||
// validate update form
|
// validate update form
|
||||||
await request.validate(UpdateUserValidator);
|
await request.validate(UpdateUserValidator);
|
||||||
|
|
||||||
// password is optional
|
// password is optional
|
||||||
let input;
|
let input;
|
||||||
if (request.input('password')) {
|
if (request.input('password')) {
|
||||||
input = request.only(['login', 'email', 'password']);
|
input = request.only(['login', 'email', 'password']);
|
||||||
} else {
|
} else {
|
||||||
input = request.only(['login', 'email']);
|
input = request.only(['login', 'email']);
|
||||||
}
|
}
|
||||||
await user.merge(input).save();
|
await user.merge(input).save();
|
||||||
// await user.save();
|
// await user.save();
|
||||||
|
|
||||||
if (request.input('roles')) {
|
if (request.input('roles')) {
|
||||||
const roles: Array<number> = request.input('roles');
|
const roles: Array<number> = request.input('roles');
|
||||||
await user.related('roles').sync(roles);
|
await user.related('roles').sync(roles);
|
||||||
}
|
}
|
||||||
|
|
||||||
session.flash('message', 'User has been updated successfully');
|
session.flash('message', 'User has been updated successfully');
|
||||||
return response.redirect().toRoute('user.index');
|
return response.redirect().toRoute('user.index');
|
||||||
}
|
}
|
||||||
|
|
||||||
public async destroy({ request, response, session }: HttpContextContract) {
|
public async destroy({ request, response, session }: HttpContextContract) {
|
||||||
const id = request.param('id');
|
const id = request.param('id');
|
||||||
const user = await User.findOrFail(id);
|
const user = await User.findOrFail(id);
|
||||||
await user.delete();
|
await user.delete();
|
||||||
|
|
||||||
session.flash('message', `User ${user.login} has been deleted.`);
|
session.flash('message', `User ${user.login} has been deleted.`);
|
||||||
return response.redirect().toRoute('user.index');
|
return response.redirect().toRoute('user.index');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show the user a form to change their personal information & password.
|
* Show the user a form to change their personal information & password.
|
||||||
*
|
*
|
||||||
* @return — \Inertia\Response
|
* @return — \Inertia\Response
|
||||||
*/
|
*/
|
||||||
public accountInfo({ inertia, auth }: HttpContextContract): RenderResponse {
|
public accountInfo({ inertia, auth }: HttpContextContract): RenderResponse {
|
||||||
const user = auth.user;
|
const user = auth.user;
|
||||||
// const id = request.param('id');
|
// const id = request.param('id');
|
||||||
// const user = await User.query().where('id', id).firstOrFail();
|
// const user = await User.query().where('id', id).firstOrFail();
|
||||||
|
|
||||||
return inertia.render('Admin/User/AccountInfo', {
|
return inertia.render('Admin/User/AccountInfo', {
|
||||||
user: user,
|
user: user,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Save the modified personal information for a user.
|
* Save the modified personal information for a user.
|
||||||
*
|
*
|
||||||
* @param HttpContextContract ctx
|
* @param HttpContextContract ctx
|
||||||
* @return : RedirectContract
|
* @return : RedirectContract
|
||||||
*/
|
*/
|
||||||
public async accountInfoStore({ request, response, auth, session }: HttpContextContract) {
|
public async accountInfoStore({ request, response, auth, session }: HttpContextContract) {
|
||||||
// validate update form
|
// validate update form
|
||||||
await request.validate(UpdateUserValidator);
|
await request.validate(UpdateUserValidator);
|
||||||
|
|
||||||
const payload = request.only(['login', 'email']);
|
const payload = request.only(['login', 'email']);
|
||||||
auth.user?.merge(payload);
|
auth.user?.merge(payload);
|
||||||
const user = await auth.user?.save();
|
const user = await auth.user?.save();
|
||||||
// $user = \Auth::user()->update($request->except(['_token']));
|
// $user = \Auth::user()->update($request->except(['_token']));
|
||||||
let message;
|
let message;
|
||||||
if (user) {
|
if (user) {
|
||||||
message = 'Account updated successfully.';
|
message = 'Account updated successfully.';
|
||||||
} else {
|
} else {
|
||||||
message = 'Error while saving. Please try again.';
|
message = 'Error while saving. Please try again.';
|
||||||
}
|
}
|
||||||
|
|
||||||
session.flash(message);
|
session.flash(message);
|
||||||
return response.redirect().toRoute('admin.account.info');
|
return response.redirect().toRoute('admin.account.info');
|
||||||
//->with('message', __($message));
|
//->with('message', __($message));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// private async syncRoles(userId: number, roleIds: Array<number>) {
|
||||||
|
// const user = await User.findOrFail(userId)
|
||||||
|
// // const roles: Role[] = await Role.query().whereIn('id', roleIds);
|
||||||
|
|
||||||
|
// // await user.roles().sync(roles.rows.map(role => role.id))
|
||||||
|
// await user.related("roles").sync(roleIds);
|
||||||
|
|
||||||
|
// return user
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,10 +25,8 @@ export default class AuthorsController {
|
||||||
if (request.input('filter')) {
|
if (request.input('filter')) {
|
||||||
// users = users.whereRaw('name like %?%', [request.input('search')])
|
// users = users.whereRaw('name like %?%', [request.input('search')])
|
||||||
const searchTerm = request.input('filter');
|
const searchTerm = request.input('filter');
|
||||||
authors
|
authors.whereILike('first_name', `%${searchTerm}%`).orWhereILike('last_name', `%${searchTerm}%`);
|
||||||
.whereILike('first_name', `%${searchTerm}%`)
|
// .orWhere('email', 'like', `%${searchTerm}%`);
|
||||||
.orWhereILike('last_name', `%${searchTerm}%`);
|
|
||||||
// .orWhere('email', 'like', `%${searchTerm}%`);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let persons = await authors;
|
let persons = await authors;
|
||||||
|
|
|
@ -4,20 +4,12 @@ import Dataset from 'App/Models/Dataset';
|
||||||
|
|
||||||
// node ace make:controller Author
|
// node ace make:controller Author
|
||||||
export default class DatasetController {
|
export default class DatasetController {
|
||||||
|
public async index({}: HttpContextContract) {
|
||||||
|
// select * from gba.persons
|
||||||
|
// where exists (select * from gba.documents inner join gba.link_documents_persons on "documents"."id" = "link_documents_persons"."document_id"
|
||||||
|
// where ("link_documents_persons"."role" = 'author') and ("persons"."id" = "link_documents_persons"."person_id"));
|
||||||
|
const datasets = await Dataset.query().where('server_state', 'published').orWhere('server_state', 'deleted');
|
||||||
|
|
||||||
public async index({}: HttpContextContract) {
|
return datasets;
|
||||||
// select * from gba.persons
|
}
|
||||||
// where exists (select * from gba.documents inner join gba.link_documents_persons on "documents"."id" = "link_documents_persons"."document_id"
|
|
||||||
// where ("link_documents_persons"."role" = 'author') and ("persons"."id" = "link_documents_persons"."person_id"));
|
|
||||||
const datasets = await Dataset
|
|
||||||
.query()
|
|
||||||
.where('server_state', 'published')
|
|
||||||
.orWhere('server_state', 'deleted');
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return datasets;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,38 +5,36 @@ import type { HttpContextContract } from '@ioc:Adonis/Core/HttpContext';
|
||||||
import AuthValidator from 'App/Validators/AuthValidator';
|
import AuthValidator from 'App/Validators/AuthValidator';
|
||||||
|
|
||||||
export default class AuthController {
|
export default class AuthController {
|
||||||
// login function
|
// login function
|
||||||
public async login({ request, response, auth, session }: HttpContextContract) {
|
public async login({ request, response, auth, session }: HttpContextContract) {
|
||||||
// console.log({
|
// console.log({
|
||||||
// registerBody: request.body(),
|
// registerBody: request.body(),
|
||||||
// });
|
// });
|
||||||
await request.validate(AuthValidator);
|
await request.validate(AuthValidator);
|
||||||
|
|
||||||
const plainPassword = await request.input('password');
|
const plainPassword = await request.input('password');
|
||||||
const email = await request.input('email');
|
const email = await request.input('email');
|
||||||
// grab uid and password values off request body
|
// grab uid and password values off request body
|
||||||
// const { email, password } = request.only(['email', 'password'])
|
// const { email, password } = request.only(['email', 'password'])
|
||||||
|
|
||||||
|
try {
|
||||||
|
// attempt to login
|
||||||
|
await auth.use('web').attempt(email, plainPassword);
|
||||||
|
} catch (error) {
|
||||||
|
// if login fails, return vague form message and redirect back
|
||||||
|
session.flash('message', 'Your username, email, or password is incorrect');
|
||||||
|
return response.redirect().back();
|
||||||
|
}
|
||||||
|
|
||||||
|
// otherwise, redirect todashboard
|
||||||
|
response.redirect('/dashboard');
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
// logout function
|
||||||
// attempt to login
|
public async logout({ auth, response }: HttpContextContract) {
|
||||||
await auth.use("web").attempt(email, plainPassword);
|
// await auth.logout();
|
||||||
} catch (error) {
|
await auth.use('web').logout();
|
||||||
// if login fails, return vague form message and redirect back
|
response.redirect('/app/login');
|
||||||
session.flash('message', 'Your username, email, or password is incorrect')
|
// return response.status(200);
|
||||||
return response.redirect().back()
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// otherwise, redirect todashboard
|
|
||||||
response.redirect('/dashboard');
|
|
||||||
}
|
|
||||||
|
|
||||||
// logout function
|
|
||||||
public async logout({ auth, response }: HttpContextContract) {
|
|
||||||
// await auth.logout();
|
|
||||||
await auth.use('web').logout();
|
|
||||||
response.redirect('/app/login');
|
|
||||||
// return response.status(200);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,33 +1,22 @@
|
||||||
import type { HttpContextContract } from '@ioc:Adonis/Core/HttpContext';
|
import type { HttpContextContract } from '@ioc:Adonis/Core/HttpContext';
|
||||||
// import User from 'App/Models/User';
|
import User from 'App/Models/User';
|
||||||
|
import Dataset from 'App/Models/Dataset';
|
||||||
// import Role from 'App/Models/Role';
|
// import Role from 'App/Models/Role';
|
||||||
// import Database from '@ioc:Adonis/Lucid/Database';
|
// import Database from '@ioc:Adonis/Lucid/Database';
|
||||||
import License from 'App/Models/License';
|
import License from 'App/Models/License';
|
||||||
import Project from 'App/Models/Project';
|
import Project from 'App/Models/Project';
|
||||||
// import type { ModelQueryBuilderContract } from '@ioc:Adonis/Lucid/Orm';
|
import Title from 'App/Models/Title';
|
||||||
|
import Description from 'App/Models/Description';
|
||||||
// import CreateUserValidator from 'App/Validators/CreateUserValidator';
|
// import CreateUserValidator from 'App/Validators/CreateUserValidator';
|
||||||
// import UpdateUserValidator from 'App/Validators/UpdateUserValidator';
|
// import UpdateUserValidator from 'App/Validators/UpdateUserValidator';
|
||||||
// import { RenderResponse } from '@ioc:EidelLev/Inertia';
|
|
||||||
import { schema, CustomMessages, rules } from '@ioc:Adonis/Core/Validator';
|
import { schema, CustomMessages, rules } from '@ioc:Adonis/Core/Validator';
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
// import Application from '@ioc:Adonis/Core/Application';
|
import Person from 'App/Models/Person';
|
||||||
|
import Database from '@ioc:Adonis/Lucid/Database';
|
||||||
enum TitleTypes {
|
import { TransactionClientContract } from '@ioc:Adonis/Lucid/Database';
|
||||||
Main = 'Main',
|
import Subject from 'App/Models/Subject';
|
||||||
Sub = 'Sub',
|
import CreateDatasetValidator from 'App/Validators/CreateDatasetValidator';
|
||||||
Alternative = 'Alternative',
|
import { TitleTypes, DescriptionTypes } from 'Contracts/enums';
|
||||||
Translated = 'Translated',
|
|
||||||
Other = 'Other',
|
|
||||||
}
|
|
||||||
|
|
||||||
enum DescriptionTypes {
|
|
||||||
Abstract = 'Abstract',
|
|
||||||
Methods = 'Methods',
|
|
||||||
Series_information = 'Series_information',
|
|
||||||
Technical_info = 'Technical_info',
|
|
||||||
Translated = 'Translated',
|
|
||||||
Other = 'Other',
|
|
||||||
}
|
|
||||||
|
|
||||||
export default class DatasetController {
|
export default class DatasetController {
|
||||||
public async create({ inertia }: HttpContextContract) {
|
public async create({ inertia }: HttpContextContract) {
|
||||||
|
@ -190,7 +179,7 @@ export default class DatasetController {
|
||||||
depth_min: schema.number.optional([rules.requiredIfExists('depth_max')]),
|
depth_min: schema.number.optional([rules.requiredIfExists('depth_max')]),
|
||||||
depth_max: schema.number.optional([rules.requiredIfExists('depth_min')]),
|
depth_max: schema.number.optional([rules.requiredIfExists('depth_min')]),
|
||||||
}),
|
}),
|
||||||
subjects: schema.array([rules.minLength(3)]).members(
|
subjects: schema.array([rules.minLength(3), rules.uniqueArray('value')]).members(
|
||||||
schema.object().members({
|
schema.object().members({
|
||||||
value: schema.string({ trim: true }, [
|
value: schema.string({ trim: true }, [
|
||||||
rules.minLength(3),
|
rules.minLength(3),
|
||||||
|
@ -214,98 +203,161 @@ export default class DatasetController {
|
||||||
}
|
}
|
||||||
return response.redirect().back();
|
return response.redirect().back();
|
||||||
}
|
}
|
||||||
public async store({ request, response, session }: HttpContextContract) {
|
public async store({ auth, request, response, session }: HttpContextContract) {
|
||||||
const newDatasetSchema = schema.create({
|
// node ace make:validator CreateDataset
|
||||||
// first step
|
|
||||||
language: schema.string({ trim: true }, [
|
|
||||||
rules.regex(/^[a-zA-Z0-9-_]+$/), //Must be alphanumeric with hyphens or underscores
|
|
||||||
]),
|
|
||||||
licenses: schema.array([rules.minLength(1)]).members(schema.number()), // define at least one license for the new dataset
|
|
||||||
rights: schema.string([rules.equalTo('true')]),
|
|
||||||
// second step
|
|
||||||
type: schema.string({ trim: true }, [rules.minLength(3), rules.maxLength(255)]),
|
|
||||||
creating_corporation: schema.string({ trim: true }, [rules.minLength(3), rules.maxLength(255)]),
|
|
||||||
titles: schema.array([rules.minLength(1)]).members(
|
|
||||||
schema.object().members({
|
|
||||||
value: schema.string({ trim: true }, [rules.minLength(3), rules.maxLength(255)]),
|
|
||||||
type: schema.enum(Object.values(TitleTypes)),
|
|
||||||
language: schema.string({ trim: true }, [
|
|
||||||
rules.minLength(2),
|
|
||||||
rules.maxLength(255),
|
|
||||||
rules.translatedLanguage('/language', 'type'),
|
|
||||||
]),
|
|
||||||
}),
|
|
||||||
),
|
|
||||||
descriptions: schema.array([rules.minLength(1)]).members(
|
|
||||||
schema.object().members({
|
|
||||||
value: schema.string({ trim: true }, [rules.minLength(3), rules.maxLength(255)]),
|
|
||||||
type: schema.enum(Object.values(DescriptionTypes)),
|
|
||||||
language: schema.string({ trim: true }, [
|
|
||||||
rules.minLength(2),
|
|
||||||
rules.maxLength(255),
|
|
||||||
rules.translatedLanguage('/language', 'type'),
|
|
||||||
]),
|
|
||||||
}),
|
|
||||||
),
|
|
||||||
authors: schema.array([rules.minLength(1)]).members(schema.object().members({ email: schema.string({ trim: true }) })),
|
|
||||||
// third step
|
|
||||||
project_id: schema.number.optional(),
|
|
||||||
embargo_date: schema.date.optional({ format: 'yyyy-MM-dd' }, [rules.after(10, 'days')]),
|
|
||||||
coverage: schema.object().members({
|
|
||||||
x_min: schema.number(),
|
|
||||||
x_max: schema.number(),
|
|
||||||
y_min: schema.number(),
|
|
||||||
y_max: schema.number(),
|
|
||||||
elevation_absolut: schema.number.optional(),
|
|
||||||
elevation_min: schema.number.optional([rules.requiredIfExists('elevation_max')]),
|
|
||||||
elevation_max: schema.number.optional([rules.requiredIfExists('elevation_min')]),
|
|
||||||
depth_absolut: schema.number.optional(),
|
|
||||||
depth_min: schema.number.optional([rules.requiredIfExists('depth_max')]),
|
|
||||||
depth_max: schema.number.optional([rules.requiredIfExists('depth_min')]),
|
|
||||||
}),
|
|
||||||
subjects: schema.array([rules.minLength(3)]).members(
|
|
||||||
schema.object().members({
|
|
||||||
value: schema.string({ trim: true }, [
|
|
||||||
rules.minLength(3),
|
|
||||||
rules.maxLength(255),
|
|
||||||
// rules.unique({ table: 'dataset_subjects', column: 'value' }),
|
|
||||||
]),
|
|
||||||
// type: schema.enum(Object.values(TitleTypes)),
|
|
||||||
language: schema.string({ trim: true }, [rules.minLength(2), rules.maxLength(255)]),
|
|
||||||
}),
|
|
||||||
),
|
|
||||||
// file: schema.file({
|
|
||||||
// size: '100mb',
|
|
||||||
// extnames: ['jpg', 'gif', 'png'],
|
|
||||||
// }),
|
|
||||||
files: schema.array([rules.minLength(1)]).members(
|
|
||||||
schema.file({
|
|
||||||
size: '100mb',
|
|
||||||
extnames: ['jpg', 'gif', 'png'],
|
|
||||||
}),
|
|
||||||
),
|
|
||||||
// upload: schema.object().members({
|
|
||||||
// label: schema.string({ trim: true }, [rules.maxLength(255)]),
|
|
||||||
|
|
||||||
// // label: schema.string({ trim: true }, [
|
|
||||||
// // // rules.minLength(3),
|
|
||||||
// // // rules.maxLength(255),
|
|
||||||
// // ]),
|
|
||||||
// }),
|
|
||||||
});
|
|
||||||
|
|
||||||
// const coverImages = request.file('files');
|
|
||||||
// node ace make:validator CreateUser
|
|
||||||
try {
|
try {
|
||||||
// Step 2 - Validate request body against the schema
|
// Step 2 - Validate request body against the schema
|
||||||
// await request.validate(CreateUserValidator);
|
// await request.validate(CreateUserValidator);
|
||||||
await request.validate({ schema: newDatasetSchema, messages: this.messages });
|
// await request.validate({ schema: newDatasetSchema, messages: this.messages });
|
||||||
|
await request.validate(CreateDatasetValidator);
|
||||||
// console.log({ payload });
|
// console.log({ payload });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// Step 3 - Handle errors
|
// Step 3 - Handle errors
|
||||||
// return response.badRequest(error.messages);
|
// return response.badRequest(error.messages);
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// const user = new User();
|
||||||
|
// user.email = 'example@example.com';
|
||||||
|
// user.password = 'password';
|
||||||
|
// await user.useTransaction(trx).save();
|
||||||
|
|
||||||
|
let trx: TransactionClientContract | null = null;
|
||||||
|
try {
|
||||||
|
trx = await Database.transaction();
|
||||||
|
const user = (await User.find(auth.user?.id)) as User;
|
||||||
|
|
||||||
|
// const dataset = await user.related('datasets').create({
|
||||||
|
// type: request.input('type'),
|
||||||
|
// creatingCorporation: request.input('creating_corporation'),
|
||||||
|
// language: request.input('language'),
|
||||||
|
// });
|
||||||
|
|
||||||
|
// Create a new instance of the Dataset model:
|
||||||
|
const dataset = new Dataset();
|
||||||
|
dataset.type = request.input('type');
|
||||||
|
dataset.creatingCorporation = request.input('creating_corporation');
|
||||||
|
dataset.language = request.input('language');
|
||||||
|
dataset.embargoDate = request.input('embargo_date');
|
||||||
|
//await dataset.related('user').associate(user); // speichert schon ab
|
||||||
|
// Dataset.$getRelation('user').boot();
|
||||||
|
// Dataset.$getRelation('user').setRelated(dataset, user);
|
||||||
|
// dataset.$setRelated('user', user);
|
||||||
|
await user.useTransaction(trx).related('datasets').save(dataset);
|
||||||
|
|
||||||
|
//store licenses:
|
||||||
|
const licenses: number[] = request.input('licenses', []);
|
||||||
|
dataset.useTransaction(trx).related('licenses').sync(licenses);
|
||||||
|
|
||||||
|
const authors = request.input('authors', []);
|
||||||
|
for (const [key, person] of authors.entries()) {
|
||||||
|
const pivotData = { role: 'author', sort_order: key + 1 };
|
||||||
|
|
||||||
|
if (person.id !== undefined) {
|
||||||
|
await dataset
|
||||||
|
.useTransaction(trx)
|
||||||
|
.related('persons')
|
||||||
|
.attach({
|
||||||
|
[person.id]: {
|
||||||
|
role: pivotData.role,
|
||||||
|
sort_order: pivotData.sort_order,
|
||||||
|
allow_email_contact: false,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
const dataPerson = new Person();
|
||||||
|
// use overwritten fill method
|
||||||
|
dataPerson.fill(person);
|
||||||
|
await dataset.useTransaction(trx).related('persons').save(dataPerson, false, {
|
||||||
|
role: pivotData.role,
|
||||||
|
sort_order: pivotData.sort_order,
|
||||||
|
allow_email_contact: false,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const contributors = request.input('contributors', []);
|
||||||
|
for (const [key, person] of contributors.entries()) {
|
||||||
|
const pivotData = { role: 'contributor', sort_order: key + 1 };
|
||||||
|
|
||||||
|
if (person.id !== undefined) {
|
||||||
|
await dataset
|
||||||
|
.useTransaction(trx)
|
||||||
|
.related('persons')
|
||||||
|
.attach({
|
||||||
|
[person.id]: {
|
||||||
|
role: pivotData.role,
|
||||||
|
sort_order: pivotData.sort_order,
|
||||||
|
allow_email_contact: false,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
const dataPerson = new Person();
|
||||||
|
// use overwritten fill method
|
||||||
|
dataPerson.fill(person);
|
||||||
|
await dataset.useTransaction(trx).related('persons').save(dataPerson, false, {
|
||||||
|
role: pivotData.role,
|
||||||
|
sort_order: pivotData.sort_order,
|
||||||
|
allow_email_contact: false,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//save main and additional titles
|
||||||
|
const titles = request.input('titles', []);
|
||||||
|
for (const titleData of titles) {
|
||||||
|
const title = new Title();
|
||||||
|
title.value = titleData.value;
|
||||||
|
title.language = titleData.language;
|
||||||
|
title.type = titleData.type;
|
||||||
|
await dataset.useTransaction(trx).related('titles').save(title);
|
||||||
|
}
|
||||||
|
|
||||||
|
//save abstract and additional descriptions
|
||||||
|
const descriptions = request.input('descriptions', []);
|
||||||
|
for (const descriptionData of descriptions) {
|
||||||
|
// $descriptionReference = new Description($description);
|
||||||
|
// $dataset->abstracts()->save($descriptionReference);
|
||||||
|
const description = new Description();
|
||||||
|
description.value = descriptionData.value;
|
||||||
|
description.language = descriptionData.language;
|
||||||
|
description.type = descriptionData.type;
|
||||||
|
await dataset.useTransaction(trx).related('descriptions').save(description);
|
||||||
|
}
|
||||||
|
|
||||||
|
//save keywords
|
||||||
|
const keywords = request.input('subjects', []);
|
||||||
|
for (const keywordData of keywords) {
|
||||||
|
// $dataKeyword = new Subject($keyword);
|
||||||
|
// $dataset->subjects()->save($dataKeyword);
|
||||||
|
const keyword = await Subject.firstOrNew({ value: keywordData.value, type: keywordData.type }, keywordData);
|
||||||
|
if (keyword.$isNew == true) {
|
||||||
|
await dataset.useTransaction(trx).related('subjects').save(keyword);
|
||||||
|
} else {
|
||||||
|
await dataset.useTransaction(trx).related('subjects').attach([keyword.id]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dataset.$getRelation('persons').boot();
|
||||||
|
// Dataset.$getRelation('persons').pushRelated(dataset, person)
|
||||||
|
// dataset.$pushRelated('persons', person);
|
||||||
|
|
||||||
|
await trx.commit();
|
||||||
|
|
||||||
|
console.log('Users and posts created successfully');
|
||||||
|
} catch (error) {
|
||||||
|
if (trx !== null) {
|
||||||
|
await trx.rollback();
|
||||||
|
}
|
||||||
|
console.error('Failed to create dataset and related models:', error);
|
||||||
|
|
||||||
|
// Handle the error and exit the controller code accordingly
|
||||||
|
// session.flash('message', 'Failed to create dataset and relaed models');
|
||||||
|
// return response.redirect().back();
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
|
||||||
|
// save data files:
|
||||||
const coverImage = request.files('files')[0];
|
const coverImage = request.files('files')[0];
|
||||||
if (coverImage) {
|
if (coverImage) {
|
||||||
// clientName: 'Gehaltsschema.png'
|
// clientName: 'Gehaltsschema.png'
|
||||||
|
@ -326,11 +378,6 @@ export default class DatasetController {
|
||||||
);
|
);
|
||||||
// let path = coverImage.filePath;
|
// let path = coverImage.filePath;
|
||||||
}
|
}
|
||||||
// const user = await User.create(input);
|
|
||||||
// if (request.input('roles')) {
|
|
||||||
// const roles: Array<number> = request.input('roles');
|
|
||||||
// await user.related('roles').attach(roles);
|
|
||||||
// }
|
|
||||||
|
|
||||||
session.flash('message', 'Dataset has been created successfully');
|
session.flash('message', 'Dataset has been created successfully');
|
||||||
// return response.redirect().toRoute('user.index');
|
// return response.redirect().toRoute('user.index');
|
||||||
|
@ -367,6 +414,7 @@ export default class DatasetController {
|
||||||
'after': `{{ field }} must be older than ${dayjs().add(10, 'day')}`,
|
'after': `{{ field }} must be older than ${dayjs().add(10, 'day')}`,
|
||||||
|
|
||||||
'subjects.minLength': 'at least {{ options.minLength }} keywords must be defined',
|
'subjects.minLength': 'at least {{ options.minLength }} keywords must be defined',
|
||||||
|
'subjects.uniqueArray': 'The {{ options.array }} array must have unique values based on the {{ options.field }} attribute.',
|
||||||
'subjects.*.value.required': 'keyword value is required',
|
'subjects.*.value.required': 'keyword value is required',
|
||||||
'subjects.*.value.minLength': 'keyword value must be at least {{ options.minLength }} characters long',
|
'subjects.*.value.minLength': 'keyword value must be at least {{ options.minLength }} characters long',
|
||||||
'subjects.*.type.required': 'keyword type is required',
|
'subjects.*.type.required': 'keyword type is required',
|
||||||
|
|
|
@ -18,44 +18,44 @@ import Logger from '@ioc:Adonis/Core/Logger';
|
||||||
import HttpExceptionHandler from '@ioc:Adonis/Core/HttpExceptionHandler';
|
import HttpExceptionHandler from '@ioc:Adonis/Core/HttpExceptionHandler';
|
||||||
|
|
||||||
export default class ExceptionHandler extends HttpExceptionHandler {
|
export default class ExceptionHandler extends HttpExceptionHandler {
|
||||||
protected statusPages = {
|
protected statusPages = {
|
||||||
'401,403': 'errors/unauthorized',
|
'401,403': 'errors/unauthorized',
|
||||||
'404': 'errors/not-found',
|
'404': 'errors/not-found',
|
||||||
'500..599': 'errors/server-error',
|
'500..599': 'errors/server-error',
|
||||||
};
|
};
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super(Logger);
|
super(Logger);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async handle(error: any, ctx: HttpContextContract) {
|
public async handle(error: any, ctx: HttpContextContract) {
|
||||||
const { response, request, inertia } = ctx;
|
const { response, request, inertia } = ctx;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle failed authentication attempt
|
* Handle failed authentication attempt
|
||||||
*/
|
*/
|
||||||
// if (['E_INVALID_AUTH_PASSWORD', 'E_INVALID_AUTH_UID'].includes(error.code)) {
|
// if (['E_INVALID_AUTH_PASSWORD', 'E_INVALID_AUTH_UID'].includes(error.code)) {
|
||||||
// session.flash('errors', { login: error.message });
|
// session.flash('errors', { login: error.message });
|
||||||
// return response.redirect('/login');
|
// return response.redirect('/login');
|
||||||
// }
|
// }
|
||||||
// if ([401].includes(error.status)) {
|
// if ([401].includes(error.status)) {
|
||||||
// session.flash('errors', { login: error.message });
|
// session.flash('errors', { login: error.message });
|
||||||
// return response.redirect('/dashboard');
|
// return response.redirect('/dashboard');
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// https://github.com/inertiajs/inertia-laravel/issues/56
|
// https://github.com/inertiajs/inertia-laravel/issues/56
|
||||||
if (request.header('X-Inertia') && [500, 503, 404, 403, 401].includes(response.getStatus())) {
|
if (request.header('X-Inertia') && [500, 503, 404, 403, 401].includes(response.getStatus())) {
|
||||||
return inertia.render('Error', {
|
return inertia.render('Error', {
|
||||||
status: response.getStatus(),
|
status: response.getStatus(),
|
||||||
message: error.message
|
message: error.message,
|
||||||
});
|
});
|
||||||
// ->toResponse($request)
|
// ->toResponse($request)
|
||||||
// ->setStatusCode($response->status());
|
// ->setStatusCode($response->status());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Forward rest of the exceptions to the parent class
|
* Forward rest of the exceptions to the parent class
|
||||||
*/
|
*/
|
||||||
return super.handle(error, ctx);
|
return super.handle(error, ctx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { Exception } from "@adonisjs/core/build/standalone";
|
import { Exception } from '@adonisjs/core/build/standalone';
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
|
@ -23,14 +23,14 @@ export default class InvalidCredentialException extends Exception {
|
||||||
* Unable to find user
|
* Unable to find user
|
||||||
*/
|
*/
|
||||||
static invalidUid() {
|
static invalidUid() {
|
||||||
const error = new this("User not found", 400, "E_INVALID_AUTH_UID");
|
const error = new this('User not found', 400, 'E_INVALID_AUTH_UID');
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Invalid user password
|
* Invalid user password
|
||||||
*/
|
*/
|
||||||
static invalidPassword() {
|
static invalidPassword() {
|
||||||
const error = new this("Password mis-match", 400, "E_INVALID_AUTH_PASSWORD");
|
const error = new this('Password mis-match', 400, 'E_INVALID_AUTH_PASSWORD');
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,18 +41,18 @@ export default class InvalidCredentialException extends Exception {
|
||||||
// if (!ctx.session) {
|
// if (!ctx.session) {
|
||||||
// return ctx.response.status(this.status).send(this.responseText);
|
// return ctx.response.status(this.status).send(this.responseText);
|
||||||
// }
|
// }
|
||||||
ctx.session.flashExcept(["_csrf"]);
|
ctx.session.flashExcept(['_csrf']);
|
||||||
ctx.session.flash("auth", {
|
ctx.session.flash('auth', {
|
||||||
error: error,
|
error: error,
|
||||||
/**
|
/**
|
||||||
* Will be removed in the future
|
* Will be removed in the future
|
||||||
*/
|
*/
|
||||||
errors: {
|
errors: {
|
||||||
uid: this.code === "E_INVALID_AUTH_UID" ? ["Invalid login id"] : null,
|
uid: this.code === 'E_INVALID_AUTH_UID' ? ['Invalid login id'] : null,
|
||||||
password: this.code === "E_INVALID_AUTH_PASSWORD" ? ["Invalid password"] : null,
|
password: this.code === 'E_INVALID_AUTH_PASSWORD' ? ['Invalid password'] : null,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
ctx.response.redirect("back", true);
|
ctx.response.redirect('back', true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { AuthenticationException } from '@adonisjs/auth/build/standalone'
|
import { AuthenticationException } from '@adonisjs/auth/build/standalone';
|
||||||
import type { GuardsList } from '@ioc:Adonis/Addons/Auth'
|
import type { GuardsList } from '@ioc:Adonis/Addons/Auth';
|
||||||
import type { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
|
import type { HttpContextContract } from '@ioc:Adonis/Core/HttpContext';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Auth middleware is meant to restrict un-authenticated access to a given route
|
* Auth middleware is meant to restrict un-authenticated access to a given route
|
||||||
|
@ -10,67 +10,58 @@ import type { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
|
||||||
* of named middleware.
|
* of named middleware.
|
||||||
*/
|
*/
|
||||||
export default class AuthMiddleware {
|
export default class AuthMiddleware {
|
||||||
/**
|
|
||||||
* The URL to redirect to when request is Unauthorized
|
|
||||||
*/
|
|
||||||
protected redirectTo = '/app/login'
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Authenticates the current HTTP request against a custom set of defined
|
|
||||||
* guards.
|
|
||||||
*
|
|
||||||
* The authentication loop stops as soon as the user is authenticated using any
|
|
||||||
* of the mentioned guards and that guard will be used by the rest of the code
|
|
||||||
* during the current request.
|
|
||||||
*/
|
|
||||||
protected async authenticate(auth: HttpContextContract['auth'], guards: (keyof GuardsList)[]) {
|
|
||||||
/**
|
/**
|
||||||
* Hold reference to the guard last attempted within the for loop. We pass
|
* The URL to redirect to when request is Unauthorized
|
||||||
* the reference of the guard to the "AuthenticationException", so that
|
|
||||||
* it can decide the correct response behavior based upon the guard
|
|
||||||
* driver
|
|
||||||
*/
|
*/
|
||||||
let guardLastAttempted: string | undefined
|
protected redirectTo = '/app/login';
|
||||||
|
|
||||||
for (let guard of guards) {
|
/**
|
||||||
guardLastAttempted = guard
|
* Authenticates the current HTTP request against a custom set of defined
|
||||||
|
* guards.
|
||||||
if (await auth.use(guard).check()) {
|
*
|
||||||
|
* The authentication loop stops as soon as the user is authenticated using any
|
||||||
|
* of the mentioned guards and that guard will be used by the rest of the code
|
||||||
|
* during the current request.
|
||||||
|
*/
|
||||||
|
protected async authenticate(auth: HttpContextContract['auth'], guards: (keyof GuardsList)[]) {
|
||||||
/**
|
/**
|
||||||
* Instruct auth to use the given guard as the default guard for
|
* Hold reference to the guard last attempted within the for loop. We pass
|
||||||
* the rest of the request, since the user authenticated
|
* the reference of the guard to the "AuthenticationException", so that
|
||||||
* succeeded here
|
* it can decide the correct response behavior based upon the guard
|
||||||
|
* driver
|
||||||
*/
|
*/
|
||||||
auth.defaultGuard = guard
|
let guardLastAttempted: string | undefined;
|
||||||
return true
|
|
||||||
}
|
for (let guard of guards) {
|
||||||
|
guardLastAttempted = guard;
|
||||||
|
|
||||||
|
if (await auth.use(guard).check()) {
|
||||||
|
/**
|
||||||
|
* Instruct auth to use the given guard as the default guard for
|
||||||
|
* the rest of the request, since the user authenticated
|
||||||
|
* succeeded here
|
||||||
|
*/
|
||||||
|
auth.defaultGuard = guard;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unable to authenticate using any guard
|
||||||
|
*/
|
||||||
|
throw new AuthenticationException('Unauthorized access', 'E_UNAUTHORIZED_ACCESS', guardLastAttempted, this.redirectTo);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unable to authenticate using any guard
|
* Handle request
|
||||||
*/
|
*/
|
||||||
throw new AuthenticationException(
|
public async handle({ auth }: HttpContextContract, next: () => Promise<void>, customGuards: (keyof GuardsList)[]) {
|
||||||
'Unauthorized access',
|
/**
|
||||||
'E_UNAUTHORIZED_ACCESS',
|
* Uses the user defined guards or the default guard mentioned in
|
||||||
guardLastAttempted,
|
* the config file
|
||||||
this.redirectTo,
|
*/
|
||||||
)
|
const guards = customGuards.length ? customGuards : [auth.name];
|
||||||
}
|
await this.authenticate(auth, guards);
|
||||||
|
await next();
|
||||||
/**
|
}
|
||||||
* Handle request
|
|
||||||
*/
|
|
||||||
public async handle (
|
|
||||||
{ auth }: HttpContextContract,
|
|
||||||
next: () => Promise<void>,
|
|
||||||
customGuards: (keyof GuardsList)[]
|
|
||||||
) {
|
|
||||||
/**
|
|
||||||
* Uses the user defined guards or the default guard mentioned in
|
|
||||||
* the config file
|
|
||||||
*/
|
|
||||||
const guards = customGuards.length ? customGuards : [auth.name]
|
|
||||||
await this.authenticate(auth, guards)
|
|
||||||
await next()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,48 +15,44 @@ const userRoleTable = Config.get('rolePermission.user_role_table', 'link_account
|
||||||
* Should be called after auth middleware
|
* Should be called after auth middleware
|
||||||
*/
|
*/
|
||||||
export default class Can {
|
export default class Can {
|
||||||
/**
|
/**
|
||||||
* Handle request
|
* Handle request
|
||||||
*/
|
*/
|
||||||
public async handle(
|
public async handle({ auth, response }: HttpContextContract, next: () => Promise<void>, permissionNames: string[]) {
|
||||||
{ auth, response }: HttpContextContract,
|
/**
|
||||||
next: () => Promise<void>,
|
* Check if user is logged-in
|
||||||
permissionNames: string[]
|
*/
|
||||||
) {
|
let user = await auth.user;
|
||||||
/**
|
if (!user) {
|
||||||
* Check if user is logged-in
|
return response.unauthorized({ error: 'Must be logged in' });
|
||||||
*/
|
}
|
||||||
let user = await auth.user;
|
let hasPermission = await this.checkHasPermissions(user, permissionNames);
|
||||||
if (!user) {
|
if (!hasPermission) {
|
||||||
return response.unauthorized({ error: 'Must be logged in' });
|
// return response.unauthorized({
|
||||||
}
|
// error: `Doesn't have required role(s): ${permissionNames.join(',')}`,
|
||||||
let hasPermission = await this.checkHasPermissions(user, permissionNames);
|
// });
|
||||||
if (!hasPermission) {
|
throw new Exception(`Doesn't have required permission(s): ${permissionNames.join(',')}`, 401);
|
||||||
// return response.unauthorized({
|
}
|
||||||
// error: `Doesn't have required role(s): ${permissionNames.join(',')}`,
|
await next();
|
||||||
// });
|
}
|
||||||
throw new Exception(`Doesn't have required permission(s): ${permissionNames.join(',')}`, 401);
|
|
||||||
}
|
|
||||||
await next();
|
|
||||||
}
|
|
||||||
|
|
||||||
private async checkHasPermissions(user: User, permissionNames: Array<string>): Promise<boolean> {
|
private async checkHasPermissions(user: User, permissionNames: Array<string>): Promise<boolean> {
|
||||||
let rolePlaceHolder = '(';
|
let rolePlaceHolder = '(';
|
||||||
let placeholders = new Array(permissionNames.length).fill('?');
|
let placeholders = new Array(permissionNames.length).fill('?');
|
||||||
rolePlaceHolder += placeholders.join(',');
|
rolePlaceHolder += placeholders.join(',');
|
||||||
rolePlaceHolder += ')';
|
rolePlaceHolder += ')';
|
||||||
|
|
||||||
// let test = user
|
// let test = user
|
||||||
// .related('roles')
|
// .related('roles')
|
||||||
// .query()
|
// .query()
|
||||||
// .count('permissions.name')
|
// .count('permissions.name')
|
||||||
// .innerJoin('gba.role_has_permissions', function () {
|
// .innerJoin('gba.role_has_permissions', function () {
|
||||||
// this.on('gba.role_has_permissions.role_id', 'roles.id');
|
// this.on('gba.role_has_permissions.role_id', 'roles.id');
|
||||||
// })
|
// })
|
||||||
// .innerJoin('gba.permissions', function () {
|
// .innerJoin('gba.permissions', function () {
|
||||||
// this.on('role_has_permissions.permission_id', 'permissions.id');
|
// this.on('role_has_permissions.permission_id', 'permissions.id');
|
||||||
// })
|
// })
|
||||||
// .andWhereIn('permissions.name', permissionNames);
|
// .andWhereIn('permissions.name', permissionNames);
|
||||||
|
|
||||||
// select "permissions"."name"
|
// select "permissions"."name"
|
||||||
// from "gba"."roles"
|
// from "gba"."roles"
|
||||||
|
@ -66,20 +62,27 @@ export default class Can {
|
||||||
// where ("permissions"."name" in ('dataset-list', 'dataset-publish'))
|
// where ("permissions"."name" in ('dataset-list', 'dataset-publish'))
|
||||||
// and ("link_accounts_roles"."account_id" = 1)
|
// and ("link_accounts_roles"."account_id" = 1)
|
||||||
|
|
||||||
let {
|
let {
|
||||||
rows: {
|
rows: {
|
||||||
0: { permissioncount },
|
0: { permissioncount },
|
||||||
},
|
},
|
||||||
} = await Database.rawQuery(
|
} = await Database.rawQuery(
|
||||||
'SELECT count("p"."name") as permissionCount FROM ' + roleTable +
|
'SELECT count("p"."name") as permissionCount FROM ' +
|
||||||
' r INNER JOIN ' + userRoleTable + ' ur ON ur.role_id=r.id AND "ur"."account_id"=? ' +
|
roleTable +
|
||||||
' INNER JOIN ' + rolePermissionTable + ' rp ON rp.role_id=r.id ' +
|
' r INNER JOIN ' +
|
||||||
' INNER JOIN ' + permissionTable + ' p ON rp.permission_id=p.id AND "p"."name" in ' +
|
userRoleTable +
|
||||||
rolePlaceHolder +
|
' ur ON ur.role_id=r.id AND "ur"."account_id"=? ' +
|
||||||
' LIMIT 1',
|
' INNER JOIN ' +
|
||||||
[user.id, ...permissionNames]
|
rolePermissionTable +
|
||||||
);
|
' rp ON rp.role_id=r.id ' +
|
||||||
|
' INNER JOIN ' +
|
||||||
|
permissionTable +
|
||||||
|
' p ON rp.permission_id=p.id AND "p"."name" in ' +
|
||||||
|
rolePlaceHolder +
|
||||||
|
' LIMIT 1',
|
||||||
|
[user.id, ...permissionNames],
|
||||||
|
);
|
||||||
|
|
||||||
return permissioncount > 0;
|
return permissioncount > 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
|
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext';
|
||||||
import Config from '@ioc:Adonis/Core/Config'
|
import Config from '@ioc:Adonis/Core/Config';
|
||||||
import Database from '@ioc:Adonis/Lucid/Database'
|
import Database from '@ioc:Adonis/Lucid/Database';
|
||||||
import User from 'App/Models/User'
|
import User from 'App/Models/User';
|
||||||
// import { Exception } from '@adonisjs/core/build/standalone'
|
// import { Exception } from '@adonisjs/core/build/standalone'
|
||||||
|
|
||||||
const roleTable = Config.get('rolePermission.role_table', 'roles')
|
const roleTable = Config.get('rolePermission.role_table', 'roles');
|
||||||
const userRoleTable = Config.get('rolePermission.user_role_table', 'user_roles')
|
const userRoleTable = Config.get('rolePermission.user_role_table', 'user_roles');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Role authentication to check if user has any of the specified roles
|
* Role authentication to check if user has any of the specified roles
|
||||||
|
@ -13,54 +13,50 @@ const userRoleTable = Config.get('rolePermission.user_role_table', 'user_roles')
|
||||||
* Should be called after auth middleware
|
* Should be called after auth middleware
|
||||||
*/
|
*/
|
||||||
export default class Is {
|
export default class Is {
|
||||||
/**
|
|
||||||
* Handle request
|
|
||||||
*/
|
|
||||||
public async handle(
|
|
||||||
{ auth, response }: HttpContextContract,
|
|
||||||
next: () => Promise<void>,
|
|
||||||
roleNames: string[]
|
|
||||||
) {
|
|
||||||
/**
|
/**
|
||||||
* Check if user is logged-in or not.
|
* Handle request
|
||||||
*/
|
*/
|
||||||
let user = await auth.user
|
public async handle({ auth, response }: HttpContextContract, next: () => Promise<void>, roleNames: string[]) {
|
||||||
if (!user) {
|
/**
|
||||||
return response.unauthorized({ error: 'Must be logged in' })
|
* Check if user is logged-in or not.
|
||||||
|
*/
|
||||||
|
let user = await auth.user;
|
||||||
|
if (!user) {
|
||||||
|
return response.unauthorized({ error: 'Must be logged in' });
|
||||||
|
}
|
||||||
|
let hasRole = await this.checkHasRoles(user, roleNames);
|
||||||
|
if (!hasRole) {
|
||||||
|
return response.unauthorized({
|
||||||
|
error: `Doesn't have required role(s): ${roleNames.join(',')}`,
|
||||||
|
});
|
||||||
|
// return new Exception(`Doesn't have required role(s): ${roleNames.join(',')}`,
|
||||||
|
// 401,
|
||||||
|
// "E_INVALID_AUTH_UID");
|
||||||
|
}
|
||||||
|
await next();
|
||||||
}
|
}
|
||||||
let hasRole = await this.checkHasRoles(user, roleNames)
|
|
||||||
if (!hasRole) {
|
private async checkHasRoles(user: User, roleNames: Array<string>): Promise<boolean> {
|
||||||
return response.unauthorized({
|
let rolePlaceHolder = '(';
|
||||||
error: `Doesn't have required role(s): ${roleNames.join(',')}`,
|
let placeholders = new Array(roleNames.length).fill('?');
|
||||||
})
|
rolePlaceHolder += placeholders.join(',');
|
||||||
// return new Exception(`Doesn't have required role(s): ${roleNames.join(',')}`,
|
rolePlaceHolder += ')';
|
||||||
// 401,
|
|
||||||
// "E_INVALID_AUTH_UID");
|
let {
|
||||||
|
0: {
|
||||||
|
0: { roleCount },
|
||||||
|
},
|
||||||
|
} = await Database.rawQuery(
|
||||||
|
'SELECT count(`ur`.`id`) as roleCount FROM ' +
|
||||||
|
userRoleTable +
|
||||||
|
' ur INNER JOIN ' +
|
||||||
|
roleTable +
|
||||||
|
' r ON ur.role_id=r.id WHERE `ur`.`user_id`=? AND `r`.`name` in ' +
|
||||||
|
rolePlaceHolder +
|
||||||
|
' LIMIT 1',
|
||||||
|
[user.id, ...roleNames],
|
||||||
|
);
|
||||||
|
|
||||||
|
return roleCount > 0;
|
||||||
}
|
}
|
||||||
await next()
|
|
||||||
}
|
|
||||||
|
|
||||||
private async checkHasRoles(user: User, roleNames: Array<string>): Promise<boolean> {
|
|
||||||
let rolePlaceHolder = '('
|
|
||||||
let placeholders = new Array(roleNames.length).fill('?')
|
|
||||||
rolePlaceHolder += placeholders.join(',')
|
|
||||||
rolePlaceHolder += ')'
|
|
||||||
|
|
||||||
let {
|
|
||||||
0: {
|
|
||||||
0: { roleCount },
|
|
||||||
},
|
|
||||||
} = await Database.rawQuery(
|
|
||||||
'SELECT count(`ur`.`id`) as roleCount FROM ' +
|
|
||||||
userRoleTable +
|
|
||||||
' ur INNER JOIN ' +
|
|
||||||
roleTable +
|
|
||||||
' r ON ur.role_id=r.id WHERE `ur`.`user_id`=? AND `r`.`name` in ' +
|
|
||||||
rolePlaceHolder +
|
|
||||||
' LIMIT 1',
|
|
||||||
[user.id, ...roleNames]
|
|
||||||
)
|
|
||||||
|
|
||||||
return roleCount > 0
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,77 +7,72 @@ import { Exception } from '@adonisjs/core/build/standalone';
|
||||||
const roleTable = Config.get('rolePermission.role_table', 'roles');
|
const roleTable = Config.get('rolePermission.role_table', 'roles');
|
||||||
const userRoleTable = Config.get('rolePermission.user_role_table', 'link_accounts_roles');
|
const userRoleTable = Config.get('rolePermission.user_role_table', 'link_accounts_roles');
|
||||||
|
|
||||||
|
|
||||||
// node ace make:middleware role
|
// node ace make:middleware role
|
||||||
export default class Role {
|
export default class Role {
|
||||||
// .middleware(['auth', 'role:admin,moderator'])
|
// .middleware(['auth', 'role:admin,moderator'])
|
||||||
public async handle(
|
public async handle({ auth, response }: HttpContextContract, next: () => Promise<void>, userRoles: string[]) {
|
||||||
{ auth, response }: HttpContextContract,
|
// Check if user is logged-in or not.
|
||||||
next: () => Promise<void>,
|
// let expression = "";
|
||||||
userRoles: string[]
|
// if (Array.isArray(args)) {
|
||||||
) {
|
// expression = args.join(" || ");
|
||||||
// Check if user is logged-in or not.
|
// }
|
||||||
// let expression = "";
|
|
||||||
// if (Array.isArray(args)) {
|
|
||||||
// expression = args.join(" || ");
|
|
||||||
// }
|
|
||||||
|
|
||||||
let user = await auth.user;
|
let user = await auth.user;
|
||||||
if (!user) {
|
if (!user) {
|
||||||
return response.unauthorized({ error: 'Must be logged in' });
|
return response.unauthorized({ error: 'Must be logged in' });
|
||||||
}
|
}
|
||||||
|
|
||||||
let hasRole = await this.checkHasRoles(user, userRoles);
|
let hasRole = await this.checkHasRoles(user, userRoles);
|
||||||
if (!hasRole) {
|
if (!hasRole) {
|
||||||
// return response.unauthorized({
|
// return response.unauthorized({
|
||||||
// error: `Doesn't have required role(s): ${userRoles.join(',')}`,
|
// error: `Doesn't have required role(s): ${userRoles.join(',')}`,
|
||||||
// // error: `Doesn't have required role(s)`,
|
// // error: `Doesn't have required role(s)`,
|
||||||
// });
|
// });
|
||||||
throw new Exception(`Doesn't have required role(s): ${userRoles.join(',')}`, 401);
|
throw new Exception(`Doesn't have required role(s): ${userRoles.join(',')}`, 401);
|
||||||
}
|
}
|
||||||
|
|
||||||
// code for middleware goes here. ABOVE THE NEXT CALL
|
// code for middleware goes here. ABOVE THE NEXT CALL
|
||||||
await next();
|
await next();
|
||||||
}
|
}
|
||||||
|
|
||||||
private async checkHasRoles(user: User, userRoles: string[]): Promise<boolean> {
|
private async checkHasRoles(user: User, userRoles: string[]): Promise<boolean> {
|
||||||
// await user.load("roles");
|
// await user.load("roles");
|
||||||
// const ok = user.roles.map((role) => role.name);
|
// const ok = user.roles.map((role) => role.name);
|
||||||
// const roles = await user.getRoles();
|
// const roles = await user.getRoles();
|
||||||
|
|
||||||
let rolePlaceHolder = '(';
|
let rolePlaceHolder = '(';
|
||||||
let placeholders = new Array(userRoles.length).fill('?');
|
let placeholders = new Array(userRoles.length).fill('?');
|
||||||
rolePlaceHolder += placeholders.join(',');
|
rolePlaceHolder += placeholders.join(',');
|
||||||
rolePlaceHolder += ')';
|
rolePlaceHolder += ')';
|
||||||
|
|
||||||
// const roles = await user
|
// const roles = await user
|
||||||
// .related('roles')
|
// .related('roles')
|
||||||
// .query()
|
// .query()
|
||||||
// .count('*') // .select('name')
|
// .count('*') // .select('name')
|
||||||
// .whereIn('name', userRoles);
|
// .whereIn('name', userRoles);
|
||||||
// // .groupBy('name');
|
// // .groupBy('name');
|
||||||
|
|
||||||
// select count(*) as roleCount
|
// select count(*) as roleCount
|
||||||
// from gba.roles
|
// from gba.roles
|
||||||
// inner join gba.link_accounts_roles
|
// inner join gba.link_accounts_roles
|
||||||
// on "roles"."id" = "link_accounts_roles"."role_id"
|
// on "roles"."id" = "link_accounts_roles"."role_id"
|
||||||
// where ("name" in ('administrator', 'editor')) and ("link_accounts_roles"."account_id" = 1)
|
// where ("name" in ('administrator', 'editor')) and ("link_accounts_roles"."account_id" = 1)
|
||||||
|
|
||||||
let {
|
let {
|
||||||
rows: {
|
rows: {
|
||||||
0: { rolecount },
|
0: { rolecount },
|
||||||
},
|
},
|
||||||
} = await Database.rawQuery(
|
} = await Database.rawQuery(
|
||||||
'SELECT count("r"."id") as roleCount FROM ' +
|
'SELECT count("r"."id") as roleCount FROM ' +
|
||||||
roleTable +
|
roleTable +
|
||||||
' r INNER JOIN ' +
|
' r INNER JOIN ' +
|
||||||
userRoleTable +
|
userRoleTable +
|
||||||
' ur ON r.id=ur.role_id WHERE "ur"."account_id"=? AND "r"."name" in ' +
|
' ur ON r.id=ur.role_id WHERE "ur"."account_id"=? AND "r"."name" in ' +
|
||||||
rolePlaceHolder +
|
rolePlaceHolder +
|
||||||
' LIMIT 1',
|
' LIMIT 1',
|
||||||
[user.id, ...userRoles]
|
[user.id, ...userRoles],
|
||||||
);
|
);
|
||||||
|
|
||||||
return rolecount > 0;
|
return rolecount > 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import type { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
|
import type { HttpContextContract } from '@ioc:Adonis/Core/HttpContext';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Silent auth middleware can be used as a global middleware to silent check
|
* Silent auth middleware can be used as a global middleware to silent check
|
||||||
|
@ -7,15 +7,15 @@ import type { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
|
||||||
* The request continues as usual, even when the user is not logged-in.
|
* The request continues as usual, even when the user is not logged-in.
|
||||||
*/
|
*/
|
||||||
export default class SilentAuthMiddleware {
|
export default class SilentAuthMiddleware {
|
||||||
/**
|
|
||||||
* Handle request
|
|
||||||
*/
|
|
||||||
public async handle({ auth }: HttpContextContract, next: () => Promise<void>) {
|
|
||||||
/**
|
/**
|
||||||
* Check if user is logged-in or not. If yes, then `ctx.auth.user` will be
|
* Handle request
|
||||||
* set to the instance of the currently logged in user.
|
|
||||||
*/
|
*/
|
||||||
await auth.check()
|
public async handle({ auth }: HttpContextContract, next: () => Promise<void>) {
|
||||||
await next()
|
/**
|
||||||
}
|
* Check if user is logged-in or not. If yes, then `ctx.auth.user` will be
|
||||||
|
* set to the instance of the currently logged in user.
|
||||||
|
*/
|
||||||
|
await auth.check();
|
||||||
|
await next();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
119
app/Models/BaseModel.ts
Normal file
119
app/Models/BaseModel.ts
Normal file
|
@ -0,0 +1,119 @@
|
||||||
|
import { BaseModel as LucidBaseModel } from '@ioc:Adonis/Lucid/Orm';
|
||||||
|
// import { ManyToManyQueryClient } from '@ioc:Adonis/Lucid/Orm';
|
||||||
|
|
||||||
|
// export class CustomManyToManyQueryClient extends ManyToManyQueryClient {
|
||||||
|
// public attach(
|
||||||
|
// relatedIds: any | any[],
|
||||||
|
// pivotAttributes: any = {},
|
||||||
|
// trx?: ReturnType<typeof this.model.transaction>
|
||||||
|
// ) {
|
||||||
|
// return super.attach(relatedIds, (row) => {
|
||||||
|
// row.pivot.fill(pivotAttributes);
|
||||||
|
// }, trx);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper to find if value is a valid Object or
|
||||||
|
* not
|
||||||
|
*/
|
||||||
|
export function isObject(value: any): boolean {
|
||||||
|
return value !== null && typeof value === 'object' && !Array.isArray(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default class BaseModel extends LucidBaseModel {
|
||||||
|
/**
|
||||||
|
* When `fill` method is called, then we may have a situation where it
|
||||||
|
* removed the values which exists in `original` and hence the dirty
|
||||||
|
* diff has to do a negative diff as well
|
||||||
|
*/
|
||||||
|
// private fillInvoked: boolean = false;
|
||||||
|
|
||||||
|
public static fillable: string[] = [];
|
||||||
|
|
||||||
|
public fill(attributes: any, allowExtraProperties: boolean = false): this {
|
||||||
|
this.$attributes = {};
|
||||||
|
// const Model = this.constructor as typeof BaseModel;
|
||||||
|
|
||||||
|
// for (const key in attributes) {
|
||||||
|
// if (Model.fillable.includes(key)) {
|
||||||
|
// const value = attributes[key];
|
||||||
|
// if (Model.$hasColumn(key)) {
|
||||||
|
// this[key] = value;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
this.mergeFillableAttributes(attributes, allowExtraProperties);
|
||||||
|
// this.fillInvoked = true;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Merge bulk attributes with existing attributes.
|
||||||
|
*
|
||||||
|
* 1. If key is unknown, it will be added to the `extras` object.
|
||||||
|
* 2. If key is defined as a relationship, it will be ignored and one must call `$setRelated`.
|
||||||
|
*/
|
||||||
|
public mergeFillableAttributes(values: any, allowExtraProperties: boolean = false): this {
|
||||||
|
const Model = this.constructor as typeof BaseModel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Merge values with the attributes
|
||||||
|
*/
|
||||||
|
if (isObject(values)) {
|
||||||
|
// Object.keys(values).forEach((key) => {
|
||||||
|
for (const key in values) {
|
||||||
|
if (Model.fillable.includes(key)) {
|
||||||
|
const value = values[key];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set as column
|
||||||
|
*/
|
||||||
|
if (Model.$hasColumn(key)) {
|
||||||
|
this[key] = value;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resolve the attribute name from the column names. Since people
|
||||||
|
* usaully define the column names directly as well by
|
||||||
|
* accepting them directly from the API.
|
||||||
|
*/
|
||||||
|
const attributeName = Model.$keys.columnsToAttributes.get(key);
|
||||||
|
if (attributeName) {
|
||||||
|
this[attributeName] = value;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If key is defined as a relation, then ignore it, since one
|
||||||
|
* must pass a qualified model to `this.$setRelated()`
|
||||||
|
*/
|
||||||
|
if (Model.$relationsDefinitions.has(key)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If the property already exists on the model, then set it
|
||||||
|
* as it is vs defining it as an extra property
|
||||||
|
*/
|
||||||
|
if (this.hasOwnProperty(key)) {
|
||||||
|
this[key] = value;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Raise error when not instructed to ignore non-existing properties.
|
||||||
|
*/
|
||||||
|
if (!allowExtraProperties) {
|
||||||
|
throw new Error(`Cannot define "${key}" on "${Model.name}" model, since it is not defined as a model property`);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.$extras[key] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,52 +1,108 @@
|
||||||
import {
|
import {
|
||||||
column,
|
column,
|
||||||
BaseModel,
|
BaseModel,
|
||||||
SnakeCaseNamingStrategy,
|
SnakeCaseNamingStrategy,
|
||||||
// computed,
|
manyToMany,
|
||||||
manyToMany,
|
ManyToMany,
|
||||||
ManyToMany,
|
belongsTo,
|
||||||
|
BelongsTo,
|
||||||
|
hasMany,
|
||||||
|
HasMany,
|
||||||
} from '@ioc:Adonis/Lucid/Orm';
|
} from '@ioc:Adonis/Lucid/Orm';
|
||||||
import { DateTime } from 'luxon';
|
import { DateTime } from 'luxon';
|
||||||
import Person from './Person';
|
import Person from './Person';
|
||||||
|
import User from './User';
|
||||||
|
import Title from './Title';
|
||||||
|
import Description from './Description';
|
||||||
|
import License from './License';
|
||||||
|
import Subject from './Subject';
|
||||||
|
|
||||||
export default class Dataset extends BaseModel {
|
export default class Dataset extends BaseModel {
|
||||||
public static namingStrategy = new SnakeCaseNamingStrategy();
|
public static namingStrategy = new SnakeCaseNamingStrategy();
|
||||||
public static primaryKey = 'id';
|
public static primaryKey = 'id';
|
||||||
public static table = 'documents';
|
public static table = 'documents';
|
||||||
public static selfAssignPrimaryKey = false;
|
public static selfAssignPrimaryKey = false;
|
||||||
|
|
||||||
@column({ isPrimary: true })
|
@column({ isPrimary: true })
|
||||||
public id: number;
|
public id: number;
|
||||||
|
|
||||||
@column({})
|
@column({})
|
||||||
public server_state: boolean;
|
public server_state: boolean;
|
||||||
|
|
||||||
@column({})
|
@column({})
|
||||||
public publisherName: string;
|
public publisherName: string;
|
||||||
|
|
||||||
|
@column({ columnName: 'creating_corporation' })
|
||||||
|
public creatingCorporation: string;
|
||||||
|
|
||||||
@column.dateTime({ columnName: 'embargo_date' })
|
@column.dateTime({ columnName: 'embargo_date' })
|
||||||
public embargoDate: DateTime;
|
public embargoDate: DateTime;
|
||||||
|
|
||||||
@column({})
|
@column({})
|
||||||
public type: string;
|
public type: string;
|
||||||
|
|
||||||
|
@column({})
|
||||||
|
public language: string;
|
||||||
|
|
||||||
@column.dateTime({ columnName: 'server_date_published' })
|
@column({})
|
||||||
public serverDatePublished: DateTime;
|
public account_id: number | null = null;
|
||||||
|
|
||||||
@column.dateTime({ autoCreate: true, columnName: 'created_at' })
|
@column.dateTime({ columnName: 'server_date_published' })
|
||||||
public createdAt: DateTime;
|
public serverDatePublished: DateTime;
|
||||||
|
|
||||||
@column.dateTime({ autoCreate: true, autoUpdate: true })
|
@column.dateTime({ autoCreate: true, columnName: 'created_at' })
|
||||||
public updatedAt: DateTime;
|
public createdAt: DateTime;
|
||||||
|
|
||||||
|
@column.dateTime({ autoCreate: true, autoUpdate: true, columnName: 'server_date_modified' })
|
||||||
|
public updatedAt: DateTime;
|
||||||
|
|
||||||
@manyToMany(() => Person, {
|
@manyToMany(() => Person, {
|
||||||
pivotForeignKey: 'document_id',
|
pivotForeignKey: 'document_id',
|
||||||
pivotRelatedForeignKey: 'person_id',
|
pivotRelatedForeignKey: 'person_id',
|
||||||
pivotTable: 'link_documents_persons',
|
pivotTable: 'link_documents_persons',
|
||||||
pivotColumns: ['role', 'sort_order', 'allow_email_contact']
|
pivotColumns: ['role', 'sort_order', 'allow_email_contact'],
|
||||||
})
|
})
|
||||||
public persons: ManyToMany<typeof Person>;
|
public persons: ManyToMany<typeof Person>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the account that the dataset belongs to
|
||||||
|
*/
|
||||||
|
@belongsTo(() => User, {
|
||||||
|
foreignKey: 'account_id',
|
||||||
|
})
|
||||||
|
public user: BelongsTo<typeof User>;
|
||||||
|
|
||||||
|
@hasMany(() => Title, {
|
||||||
|
foreignKey: 'document_id',
|
||||||
|
})
|
||||||
|
public titles: HasMany<typeof Title>;
|
||||||
|
|
||||||
|
@hasMany(() => Description, {
|
||||||
|
foreignKey: 'document_id',
|
||||||
|
})
|
||||||
|
public descriptions: HasMany<typeof Description>;
|
||||||
|
|
||||||
|
@manyToMany(() => License, {
|
||||||
|
pivotForeignKey: 'document_id',
|
||||||
|
pivotRelatedForeignKey: 'licence_id',
|
||||||
|
pivotTable: 'link_documents_licences',
|
||||||
|
})
|
||||||
|
public licenses: ManyToMany<typeof License>;
|
||||||
|
|
||||||
|
// public function subjects()
|
||||||
|
// {
|
||||||
|
// return $this->belongsToMany(\App\Models\Subject::class, 'link_dataset_subjects', 'document_id', 'subject_id');
|
||||||
|
// }
|
||||||
|
@manyToMany(() => Subject, {
|
||||||
|
pivotForeignKey: 'document_id',
|
||||||
|
pivotRelatedForeignKey: 'subject_id',
|
||||||
|
pivotTable: 'link_dataset_subjects',
|
||||||
|
})
|
||||||
|
public subjects: ManyToMany<typeof Subject>;
|
||||||
|
|
||||||
|
// async save(): Promise<this> {
|
||||||
|
// // Call the parent save method to persist changes to the database
|
||||||
|
// await super.save();
|
||||||
|
// return this;
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
28
app/Models/Description.ts
Normal file
28
app/Models/Description.ts
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
import { column, belongsTo, BelongsTo } from '@ioc:Adonis/Lucid/Orm';
|
||||||
|
import Dataset from './Dataset';
|
||||||
|
import BaseModel from './BaseModel';
|
||||||
|
|
||||||
|
export default class Description extends BaseModel {
|
||||||
|
public static primaryKey = 'id';
|
||||||
|
public static table = 'dataset_abstracts';
|
||||||
|
public static selfAssignPrimaryKey = false;
|
||||||
|
public static timestamps = false;
|
||||||
|
public static fillable: string[] = ['value', 'type', 'language'];
|
||||||
|
|
||||||
|
@column({})
|
||||||
|
public document_id: number;
|
||||||
|
|
||||||
|
@column()
|
||||||
|
public type: string;
|
||||||
|
|
||||||
|
@column()
|
||||||
|
public value: string;
|
||||||
|
|
||||||
|
@column()
|
||||||
|
public language: string;
|
||||||
|
|
||||||
|
@belongsTo(() => Dataset, {
|
||||||
|
foreignKey: 'document_id',
|
||||||
|
})
|
||||||
|
public dataset: BelongsTo<typeof Dataset>;
|
||||||
|
}
|
|
@ -1,54 +1,55 @@
|
||||||
import { DateTime } from 'luxon';
|
import { DateTime } from 'luxon';
|
||||||
import {
|
import {
|
||||||
column,
|
column,
|
||||||
BaseModel,
|
BaseModel,
|
||||||
hasMany, HasMany,
|
hasMany,
|
||||||
// manyToMany,
|
HasMany,
|
||||||
// ManyToMany,
|
// manyToMany,
|
||||||
SnakeCaseNamingStrategy,
|
// ManyToMany,
|
||||||
|
SnakeCaseNamingStrategy,
|
||||||
} from '@ioc:Adonis/Lucid/Orm';
|
} from '@ioc:Adonis/Lucid/Orm';
|
||||||
import HashValue from './HashValue';
|
import HashValue from './HashValue';
|
||||||
|
|
||||||
export default class File extends BaseModel {
|
export default class File extends BaseModel {
|
||||||
public static namingStrategy = new SnakeCaseNamingStrategy();
|
public static namingStrategy = new SnakeCaseNamingStrategy();
|
||||||
public static primaryKey = 'id';
|
public static primaryKey = 'id';
|
||||||
public static table = 'document_files';
|
public static table = 'document_files';
|
||||||
public static selfAssignPrimaryKey = false;
|
public static selfAssignPrimaryKey = false;
|
||||||
|
|
||||||
@column({
|
@column({
|
||||||
isPrimary: true,
|
isPrimary: true,
|
||||||
})
|
})
|
||||||
public id: number;
|
public id: number;
|
||||||
|
|
||||||
@column({})
|
@column({})
|
||||||
public pathName: string;
|
public pathName: string;
|
||||||
|
|
||||||
@column()
|
|
||||||
public label: string;
|
|
||||||
|
|
||||||
@column()
|
@column()
|
||||||
public comment: string;
|
public label: string;
|
||||||
|
|
||||||
@column()
|
@column()
|
||||||
public mimetype: string;
|
public comment: string;
|
||||||
|
|
||||||
@column()
|
@column()
|
||||||
public language: string;
|
public mimetype: string;
|
||||||
|
|
||||||
@column()
|
@column()
|
||||||
public fileSize: bigint;
|
public language: string;
|
||||||
|
|
||||||
@column()
|
@column()
|
||||||
public visibleInOai: boolean;
|
public fileSize: bigint;
|
||||||
|
|
||||||
@column()
|
@column()
|
||||||
public sortOrder: number;
|
public visibleInOai: boolean;
|
||||||
|
|
||||||
|
@column()
|
||||||
|
public sortOrder: number;
|
||||||
|
|
||||||
@column.dateTime({ autoCreate: true })
|
@column.dateTime({ autoCreate: true })
|
||||||
public createdAt: DateTime;
|
public createdAt: DateTime;
|
||||||
|
|
||||||
@column.dateTime({ autoCreate: true, autoUpdate: true })
|
@column.dateTime({ autoCreate: true, autoUpdate: true })
|
||||||
public updatedAt: DateTime;
|
public updatedAt: DateTime;
|
||||||
|
|
||||||
// public function hashvalues()
|
// public function hashvalues()
|
||||||
// {
|
// {
|
||||||
|
@ -58,5 +59,5 @@ export default class File extends BaseModel {
|
||||||
@hasMany(() => HashValue, {
|
@hasMany(() => HashValue, {
|
||||||
foreignKey: 'file_id',
|
foreignKey: 'file_id',
|
||||||
})
|
})
|
||||||
public hashvalues: HasMany<typeof HashValue>;
|
public hashvalues: HasMany<typeof HashValue>;
|
||||||
}
|
}
|
|
@ -1,41 +1,34 @@
|
||||||
import {
|
import { column, BaseModel, belongsTo, BelongsTo, SnakeCaseNamingStrategy } from '@ioc:Adonis/Lucid/Orm';
|
||||||
column,
|
|
||||||
BaseModel,
|
|
||||||
belongsTo,
|
|
||||||
BelongsTo,
|
|
||||||
SnakeCaseNamingStrategy,
|
|
||||||
} from '@ioc:Adonis/Lucid/Orm';
|
|
||||||
import File from './File';
|
import File from './File';
|
||||||
|
|
||||||
export default class HashValue extends BaseModel {
|
export default class HashValue extends BaseModel {
|
||||||
public static namingStrategy = new SnakeCaseNamingStrategy();
|
public static namingStrategy = new SnakeCaseNamingStrategy();
|
||||||
public static primaryKey = 'file_id, type';
|
public static primaryKey = 'file_id, type';
|
||||||
public static table = 'file_hashvalues';
|
public static table = 'file_hashvalues';
|
||||||
|
|
||||||
// static get primaryKey () {
|
// static get primaryKey () {
|
||||||
// return 'type, value'
|
// return 'type, value'
|
||||||
// }
|
// }
|
||||||
|
|
||||||
static get incrementing () {
|
static get incrementing() {
|
||||||
return false
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// @column({
|
// @column({
|
||||||
// isPrimary: true,
|
// isPrimary: true,
|
||||||
// })
|
// })
|
||||||
// public id: number;
|
// public id: number;
|
||||||
|
|
||||||
// Foreign key is still on the same model
|
// Foreign key is still on the same model
|
||||||
@column({})
|
@column({})
|
||||||
public file_id: number;
|
public file_id: number;
|
||||||
|
|
||||||
@column({})
|
@column({})
|
||||||
public type: string;
|
public type: string;
|
||||||
|
|
||||||
@column()
|
@column()
|
||||||
public value: string;
|
public value: string;
|
||||||
|
|
||||||
@belongsTo(() => File)
|
@belongsTo(() => File)
|
||||||
public file: BelongsTo<typeof File>
|
public file: BelongsTo<typeof File>;
|
||||||
|
|
||||||
}
|
}
|
|
@ -5,6 +5,22 @@ export default class License extends BaseModel {
|
||||||
public static primaryKey = 'id';
|
public static primaryKey = 'id';
|
||||||
public static table = 'document_licences';
|
public static table = 'document_licences';
|
||||||
public static selfAssignPrimaryKey = false;
|
public static selfAssignPrimaryKey = false;
|
||||||
|
public static timestamps = false;
|
||||||
|
public static fillable: string[] = [
|
||||||
|
'name_long',
|
||||||
|
'name',
|
||||||
|
'language',
|
||||||
|
'link_licence',
|
||||||
|
'link_logo',
|
||||||
|
'desc_text',
|
||||||
|
'desc_markup',
|
||||||
|
'comment_internal',
|
||||||
|
'mime_type',
|
||||||
|
'sort_order',
|
||||||
|
'language',
|
||||||
|
'active',
|
||||||
|
'pod_allowed',
|
||||||
|
];
|
||||||
|
|
||||||
@column({
|
@column({
|
||||||
isPrimary: true,
|
isPrimary: true,
|
||||||
|
|
|
@ -1,100 +1,92 @@
|
||||||
import {
|
import { column, BaseModel, manyToMany, ManyToMany, SnakeCaseNamingStrategy, beforeUpdate, beforeCreate } from '@ioc:Adonis/Lucid/Orm';
|
||||||
column,
|
|
||||||
BaseModel,
|
|
||||||
manyToMany,
|
|
||||||
ManyToMany,
|
|
||||||
SnakeCaseNamingStrategy,
|
|
||||||
beforeUpdate,
|
|
||||||
beforeCreate,
|
|
||||||
} from '@ioc:Adonis/Lucid/Orm';
|
|
||||||
import { DateTime } from 'luxon';
|
import { DateTime } from 'luxon';
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
import Role from 'App/Models/Role';
|
import Role from 'App/Models/Role';
|
||||||
|
|
||||||
export default class Permission extends BaseModel {
|
export default class Permission extends BaseModel {
|
||||||
public static namingStrategy = new SnakeCaseNamingStrategy();
|
public static namingStrategy = new SnakeCaseNamingStrategy();
|
||||||
public static primaryKey = 'id';
|
public static primaryKey = 'id';
|
||||||
public static table = 'permissions';
|
public static table = 'permissions';
|
||||||
public static selfAssignPrimaryKey = false;
|
public static selfAssignPrimaryKey = false;
|
||||||
|
|
||||||
@column({
|
@column({
|
||||||
isPrimary: true,
|
isPrimary: true,
|
||||||
})
|
})
|
||||||
public id: number;
|
public id: number;
|
||||||
|
|
||||||
@column({})
|
@column({})
|
||||||
public role_id: number;
|
public role_id: number;
|
||||||
|
|
||||||
@column({})
|
@column({})
|
||||||
public display_name: string;
|
public display_name: string;
|
||||||
|
|
||||||
@column({})
|
@column({})
|
||||||
public name: string;
|
public name: string;
|
||||||
|
|
||||||
@column({})
|
@column({})
|
||||||
public description: string;
|
public description: string;
|
||||||
|
|
||||||
@column.dateTime({
|
@column.dateTime({
|
||||||
serialize: (value: Date | null) => {
|
serialize: (value: Date | null) => {
|
||||||
return value ? dayjs(value).format('MMMM D YYYY HH:mm a') : value;
|
return value ? dayjs(value).format('MMMM D YYYY HH:mm a') : value;
|
||||||
},
|
},
|
||||||
autoCreate: true,
|
autoCreate: true,
|
||||||
})
|
})
|
||||||
public created_at: DateTime;
|
public created_at: DateTime;
|
||||||
|
|
||||||
@column.dateTime({
|
@column.dateTime({
|
||||||
serialize: (value: Date | null) => {
|
serialize: (value: Date | null) => {
|
||||||
return value ? dayjs(value).format('MMMM D YYYY HH:mm a') : value;
|
return value ? dayjs(value).format('MMMM D YYYY HH:mm a') : value;
|
||||||
},
|
},
|
||||||
autoCreate: true,
|
autoCreate: true,
|
||||||
autoUpdate: true,
|
autoUpdate: true,
|
||||||
})
|
})
|
||||||
public updated_at: DateTime;
|
public updated_at: DateTime;
|
||||||
|
|
||||||
@beforeCreate()
|
@beforeCreate()
|
||||||
@beforeUpdate()
|
@beforeUpdate()
|
||||||
public static async resetDate(role) {
|
public static async resetDate(role) {
|
||||||
role.created_at = this.formatDateTime(role.created_at);
|
role.created_at = this.formatDateTime(role.created_at);
|
||||||
role.updated_at = this.formatDateTime(role.updated_at);
|
role.updated_at = this.formatDateTime(role.updated_at);
|
||||||
}
|
}
|
||||||
|
|
||||||
// public static boot() {
|
// public static boot() {
|
||||||
// super.boot()
|
// super.boot()
|
||||||
|
|
||||||
// this.before('create', async (_modelInstance) => {
|
// this.before('create', async (_modelInstance) => {
|
||||||
// _modelInstance.created_at = this.formatDateTime(_modelInstance.created_at)
|
// _modelInstance.created_at = this.formatDateTime(_modelInstance.created_at)
|
||||||
// _modelInstance.updated_at = this.formatDateTime(_modelInstance.updated_at)
|
// _modelInstance.updated_at = this.formatDateTime(_modelInstance.updated_at)
|
||||||
// })
|
// })
|
||||||
// this.before('update', async (_modelInstance) => {
|
// this.before('update', async (_modelInstance) => {
|
||||||
// _modelInstance.created_at = this.formatDateTime(_modelInstance.created_at)
|
// _modelInstance.created_at = this.formatDateTime(_modelInstance.created_at)
|
||||||
// _modelInstance.updated_at = this.formatDateTime(_modelInstance.updated_at)
|
// _modelInstance.updated_at = this.formatDateTime(_modelInstance.updated_at)
|
||||||
// })
|
// })
|
||||||
// }
|
// }
|
||||||
|
|
||||||
private static formatDateTime(datetime) {
|
private static formatDateTime(datetime) {
|
||||||
let value = new Date(datetime);
|
let value = new Date(datetime);
|
||||||
return datetime
|
return datetime
|
||||||
? value.getFullYear() +
|
? value.getFullYear() +
|
||||||
'-' +
|
'-' +
|
||||||
(value.getMonth() + 1) +
|
(value.getMonth() + 1) +
|
||||||
'-' +
|
'-' +
|
||||||
value.getDate() +
|
value.getDate() +
|
||||||
' ' +
|
' ' +
|
||||||
value.getHours() +
|
value.getHours() +
|
||||||
':' +
|
':' +
|
||||||
value.getMinutes() +
|
value.getMinutes() +
|
||||||
':' +
|
':' +
|
||||||
value.getSeconds()
|
value.getSeconds()
|
||||||
: datetime;
|
: datetime;
|
||||||
}
|
}
|
||||||
|
|
||||||
// @belongsTo(() => Role)
|
// @belongsTo(() => Role)
|
||||||
// public role: BelongsTo<typeof Role>;
|
// public role: BelongsTo<typeof Role>;
|
||||||
|
|
||||||
@manyToMany(() => Role, {
|
@manyToMany(() => Role, {
|
||||||
pivotForeignKey: 'permission_id',
|
pivotForeignKey: 'permission_id',
|
||||||
pivotRelatedForeignKey: 'role_id',
|
pivotRelatedForeignKey: 'role_id',
|
||||||
pivotTable: 'role_has_permissions',
|
pivotTable: 'role_has_permissions',
|
||||||
})
|
})
|
||||||
public roles: ManyToMany<typeof Role>;
|
public roles: ManyToMany<typeof Role>;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,83 +1,79 @@
|
||||||
import {
|
import { column, SnakeCaseNamingStrategy, computed, manyToMany, ManyToMany } from '@ioc:Adonis/Lucid/Orm';
|
||||||
column,
|
|
||||||
BaseModel,
|
|
||||||
SnakeCaseNamingStrategy,
|
|
||||||
computed,
|
|
||||||
manyToMany,
|
|
||||||
ManyToMany,
|
|
||||||
} from '@ioc:Adonis/Lucid/Orm';
|
|
||||||
import { DateTime } from 'luxon';
|
import { DateTime } from 'luxon';
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
import Dataset from './Dataset';
|
import Dataset from './Dataset';
|
||||||
|
import BaseModel from './BaseModel';
|
||||||
|
|
||||||
export default class Person extends BaseModel {
|
export default class Person extends BaseModel {
|
||||||
public static namingStrategy = new SnakeCaseNamingStrategy();
|
public static namingStrategy = new SnakeCaseNamingStrategy();
|
||||||
public static primaryKey = 'id';
|
public static primaryKey = 'id';
|
||||||
public static table = 'persons';
|
public static table = 'persons';
|
||||||
public static selfAssignPrimaryKey = false;
|
public static selfAssignPrimaryKey = false;
|
||||||
|
// only the academic_title, email, first_name, identifier_orcid, last_name and name_type attributes are allowed to be mass assigned.
|
||||||
|
public static fillable: string[] = ['academic_title', 'email', 'first_name', 'identifier_orcid', 'last_name', 'name_type'];
|
||||||
|
|
||||||
@column({
|
@column({
|
||||||
isPrimary: true,
|
isPrimary: true,
|
||||||
})
|
|
||||||
public id: number;
|
|
||||||
|
|
||||||
@column({})
|
|
||||||
public academicTitle: string;
|
|
||||||
|
|
||||||
@column()
|
|
||||||
public email: string;
|
|
||||||
|
|
||||||
@column({})
|
|
||||||
public firstName: string;
|
|
||||||
|
|
||||||
@column({})
|
|
||||||
public lastName: string;
|
|
||||||
|
|
||||||
@column({})
|
|
||||||
public identifierOrcid: string;
|
|
||||||
|
|
||||||
@column({})
|
|
||||||
public status: boolean;
|
|
||||||
|
|
||||||
@column({})
|
|
||||||
public nameType: string;
|
|
||||||
|
|
||||||
@column.dateTime({
|
|
||||||
serialize: (value: Date | null) => {
|
|
||||||
return value ? dayjs(value).format('MMMM D YYYY HH:mm a') : value;
|
|
||||||
},
|
|
||||||
autoCreate: true,
|
|
||||||
})
|
|
||||||
public createdAt: DateTime;
|
|
||||||
|
|
||||||
@computed({
|
|
||||||
serializeAs: 'name'
|
|
||||||
})
|
})
|
||||||
public get fullName() {
|
public id: number;
|
||||||
return `${this.firstName} ${this.lastName}`;
|
|
||||||
}
|
@column({ columnName: 'academic_title' })
|
||||||
|
public academicTitle: string;
|
||||||
|
|
||||||
|
@column()
|
||||||
|
public email: string;
|
||||||
|
|
||||||
|
@column({})
|
||||||
|
public firstName: string;
|
||||||
|
|
||||||
|
@column({})
|
||||||
|
public lastName: string;
|
||||||
|
|
||||||
|
@column({})
|
||||||
|
public identifierOrcid: string;
|
||||||
|
|
||||||
|
@column({})
|
||||||
|
public status: boolean;
|
||||||
|
|
||||||
|
@column({})
|
||||||
|
public nameType: string;
|
||||||
|
|
||||||
|
@column.dateTime({
|
||||||
|
serialize: (value: Date | null) => {
|
||||||
|
return value ? dayjs(value).format('MMMM D YYYY HH:mm a') : value;
|
||||||
|
},
|
||||||
|
autoCreate: true,
|
||||||
|
})
|
||||||
|
public createdAt: DateTime;
|
||||||
|
|
||||||
|
@computed({
|
||||||
|
serializeAs: 'name',
|
||||||
|
})
|
||||||
|
public get fullName() {
|
||||||
|
return `${this.firstName} ${this.lastName}`;
|
||||||
|
}
|
||||||
|
|
||||||
// @computed()
|
// @computed()
|
||||||
// public get progress(): number {
|
// public get progress(): number {
|
||||||
// return 50;
|
// return 50;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// @computed()
|
// @computed()
|
||||||
// public get created_at() {
|
// public get created_at() {
|
||||||
// return '2023-03-21 08:45:00';
|
// return '2023-03-21 08:45:00';
|
||||||
// }
|
// }
|
||||||
|
|
||||||
@computed()
|
@computed()
|
||||||
public get datasetCount() {
|
public get datasetCount() {
|
||||||
const stock = this.$extras.datasets_count //my pivot column name was "stock"
|
const stock = this.$extras.datasets_count; //my pivot column name was "stock"
|
||||||
return stock
|
return stock;
|
||||||
}
|
}
|
||||||
|
|
||||||
@manyToMany(() => Dataset, {
|
@manyToMany(() => Dataset, {
|
||||||
pivotForeignKey: 'person_id',
|
pivotForeignKey: 'person_id',
|
||||||
pivotRelatedForeignKey: 'document_id',
|
pivotRelatedForeignKey: 'document_id',
|
||||||
pivotTable: 'link_documents_persons',
|
pivotTable: 'link_documents_persons',
|
||||||
pivotColumns: ['role', 'sort_order', 'allow_email_contact']
|
pivotColumns: ['role', 'sort_order', 'allow_email_contact'],
|
||||||
})
|
})
|
||||||
public datasets: ManyToMany<typeof Dataset>;
|
public datasets: ManyToMany<typeof Dataset>;
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,6 @@ export default class Project extends BaseModel {
|
||||||
})
|
})
|
||||||
public id: number;
|
public id: number;
|
||||||
|
|
||||||
|
|
||||||
@column({})
|
@column({})
|
||||||
public label: string;
|
public label: string;
|
||||||
|
|
||||||
|
@ -24,14 +23,12 @@ export default class Project extends BaseModel {
|
||||||
|
|
||||||
@column.dateTime({
|
@column.dateTime({
|
||||||
autoCreate: true,
|
autoCreate: true,
|
||||||
})
|
})
|
||||||
public created_at: DateTime;
|
public created_at: DateTime;
|
||||||
|
|
||||||
@column.dateTime({
|
@column.dateTime({
|
||||||
autoCreate: true,
|
autoCreate: true,
|
||||||
autoUpdate: true
|
autoUpdate: true,
|
||||||
})
|
})
|
||||||
public updated_at: DateTime;
|
public updated_at: DateTime;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,4 @@
|
||||||
import {
|
import { column, BaseModel, SnakeCaseNamingStrategy, manyToMany, ManyToMany, beforeCreate, beforeUpdate } from '@ioc:Adonis/Lucid/Orm';
|
||||||
column,
|
|
||||||
BaseModel,
|
|
||||||
SnakeCaseNamingStrategy,
|
|
||||||
manyToMany,
|
|
||||||
ManyToMany,
|
|
||||||
beforeCreate,
|
|
||||||
beforeUpdate,
|
|
||||||
} from '@ioc:Adonis/Lucid/Orm';
|
|
||||||
|
|
||||||
import { DateTime } from 'luxon';
|
import { DateTime } from 'luxon';
|
||||||
// import moment from 'moment';
|
// import moment from 'moment';
|
||||||
|
@ -15,91 +7,91 @@ import User from './User';
|
||||||
import Permission from 'App/Models/Permission';
|
import Permission from 'App/Models/Permission';
|
||||||
|
|
||||||
export default class Role extends BaseModel {
|
export default class Role extends BaseModel {
|
||||||
public static namingStrategy = new SnakeCaseNamingStrategy();
|
public static namingStrategy = new SnakeCaseNamingStrategy();
|
||||||
public static primaryKey = 'id';
|
public static primaryKey = 'id';
|
||||||
public static table = 'roles';
|
public static table = 'roles';
|
||||||
public static selfAssignPrimaryKey = false;
|
public static selfAssignPrimaryKey = false;
|
||||||
|
|
||||||
@column({
|
@column({
|
||||||
isPrimary: true,
|
isPrimary: true,
|
||||||
})
|
})
|
||||||
public id: number;
|
public id: number;
|
||||||
|
|
||||||
@column({})
|
@column({})
|
||||||
public display_name: string;
|
public display_name: string;
|
||||||
|
|
||||||
@column({})
|
@column({})
|
||||||
public name: string;
|
public name: string;
|
||||||
|
|
||||||
@column({})
|
@column({})
|
||||||
public description: string;
|
public description: string;
|
||||||
|
|
||||||
@column.dateTime({
|
@column.dateTime({
|
||||||
serialize: (value: Date | null) => {
|
serialize: (value: Date | null) => {
|
||||||
// return value ? moment(value).format('MMMM Do YYYY, HH:mm:ss') : value;
|
// return value ? moment(value).format('MMMM Do YYYY, HH:mm:ss') : value;
|
||||||
return value ? dayjs(value).format('MMMM D YYYY HH:mm a') : value;
|
return value ? dayjs(value).format('MMMM D YYYY HH:mm a') : value;
|
||||||
},
|
},
|
||||||
autoCreate: true,
|
autoCreate: true,
|
||||||
})
|
})
|
||||||
public created_at: DateTime;
|
public created_at: DateTime;
|
||||||
|
|
||||||
@column.dateTime({
|
@column.dateTime({
|
||||||
serialize: (value: Date | null) => {
|
serialize: (value: Date | null) => {
|
||||||
return value ? dayjs(value).format('MMMM D YYYY HH:mm a') : value;
|
return value ? dayjs(value).format('MMMM D YYYY HH:mm a') : value;
|
||||||
},
|
},
|
||||||
autoCreate: true,
|
autoCreate: true,
|
||||||
autoUpdate: true
|
autoUpdate: true,
|
||||||
})
|
})
|
||||||
public updated_at: DateTime;
|
public updated_at: DateTime;
|
||||||
|
|
||||||
@beforeCreate()
|
@beforeCreate()
|
||||||
@beforeUpdate()
|
@beforeUpdate()
|
||||||
public static async resetDate(role) {
|
public static async resetDate(role) {
|
||||||
role.created_at = this.formatDateTime(role.created_at);
|
role.created_at = this.formatDateTime(role.created_at);
|
||||||
role.updated_at = this.formatDateTime(role.updated_at);
|
role.updated_at = this.formatDateTime(role.updated_at);
|
||||||
}
|
}
|
||||||
|
|
||||||
// public static boot() {
|
// public static boot() {
|
||||||
// super.boot();
|
// super.boot();
|
||||||
|
|
||||||
// this.before('create', async (_modelInstance) => {
|
// this.before('create', async (_modelInstance) => {
|
||||||
// _modelInstance.created_at = this.formatDateTime(_modelInstance.created_at);
|
// _modelInstance.created_at = this.formatDateTime(_modelInstance.created_at);
|
||||||
// _modelInstance.updated_at = this.formatDateTime(_modelInstance.updated_at);
|
// _modelInstance.updated_at = this.formatDateTime(_modelInstance.updated_at);
|
||||||
// });
|
// });
|
||||||
// this.before('update', async (_modelInstance) => {
|
// this.before('update', async (_modelInstance) => {
|
||||||
// _modelInstance.created_at = this.formatDateTime(_modelInstance.created_at);
|
// _modelInstance.created_at = this.formatDateTime(_modelInstance.created_at);
|
||||||
// _modelInstance.updated_at = this.formatDateTime(_modelInstance.updated_at);
|
// _modelInstance.updated_at = this.formatDateTime(_modelInstance.updated_at);
|
||||||
// });
|
// });
|
||||||
// }
|
// }
|
||||||
|
|
||||||
private static formatDateTime(datetime) {
|
private static formatDateTime(datetime) {
|
||||||
let value = new Date(datetime);
|
let value = new Date(datetime);
|
||||||
return datetime
|
return datetime
|
||||||
? value.getFullYear() +
|
? value.getFullYear() +
|
||||||
'-' +
|
'-' +
|
||||||
(value.getMonth() + 1) +
|
(value.getMonth() + 1) +
|
||||||
'-' +
|
'-' +
|
||||||
value.getDate() +
|
value.getDate() +
|
||||||
' ' +
|
' ' +
|
||||||
value.getHours() +
|
value.getHours() +
|
||||||
':' +
|
':' +
|
||||||
value.getMinutes() +
|
value.getMinutes() +
|
||||||
':' +
|
':' +
|
||||||
value.getSeconds()
|
value.getSeconds()
|
||||||
: datetime;
|
: datetime;
|
||||||
}
|
}
|
||||||
|
|
||||||
@manyToMany(() => User, {
|
@manyToMany(() => User, {
|
||||||
pivotForeignKey: 'role_id',
|
pivotForeignKey: 'role_id',
|
||||||
pivotRelatedForeignKey: 'account_id',
|
pivotRelatedForeignKey: 'account_id',
|
||||||
pivotTable: 'link_accounts_roles',
|
pivotTable: 'link_accounts_roles',
|
||||||
})
|
})
|
||||||
public users: ManyToMany<typeof User>;
|
public users: ManyToMany<typeof User>;
|
||||||
|
|
||||||
@manyToMany(() => Permission, {
|
@manyToMany(() => Permission, {
|
||||||
pivotForeignKey: 'role_id',
|
pivotForeignKey: 'role_id',
|
||||||
pivotRelatedForeignKey: 'permission_id',
|
pivotRelatedForeignKey: 'permission_id',
|
||||||
pivotTable: 'role_has_permissions',
|
pivotTable: 'role_has_permissions',
|
||||||
})
|
})
|
||||||
public permissions: ManyToMany<typeof Permission>;
|
public permissions: ManyToMany<typeof Permission>;
|
||||||
}
|
}
|
||||||
|
|
28
app/Models/Title.ts
Normal file
28
app/Models/Title.ts
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
import { column, belongsTo, BelongsTo } from '@ioc:Adonis/Lucid/Orm';
|
||||||
|
import Dataset from './Dataset';
|
||||||
|
import BaseModel from './BaseModel';
|
||||||
|
|
||||||
|
export default class Title extends BaseModel {
|
||||||
|
public static primaryKey = 'id';
|
||||||
|
public static table = 'dataset_titles';
|
||||||
|
public static selfAssignPrimaryKey = false;
|
||||||
|
public static timestamps = false;
|
||||||
|
public static fillable: string[] = ['value', 'type', 'language'];
|
||||||
|
|
||||||
|
@column({})
|
||||||
|
public document_id: number;
|
||||||
|
|
||||||
|
@column()
|
||||||
|
public type: string;
|
||||||
|
|
||||||
|
@column()
|
||||||
|
public value: string;
|
||||||
|
|
||||||
|
@column()
|
||||||
|
public language: string;
|
||||||
|
|
||||||
|
@belongsTo(() => Dataset, {
|
||||||
|
foreignKey: 'document_id',
|
||||||
|
})
|
||||||
|
public dataset: BelongsTo<typeof Dataset>;
|
||||||
|
}
|
|
@ -1,9 +1,10 @@
|
||||||
import { DateTime } from 'luxon';
|
import { DateTime } from 'luxon';
|
||||||
import { BaseModel, column, beforeSave, manyToMany, ManyToMany } from '@ioc:Adonis/Lucid/Orm';
|
import { BaseModel, column, beforeSave, manyToMany, ManyToMany, hasMany, HasMany } from '@ioc:Adonis/Lucid/Orm';
|
||||||
import Hash from '@ioc:Adonis/Core/Hash';
|
import Hash from '@ioc:Adonis/Core/Hash';
|
||||||
import Role from './Role';
|
import Role from './Role';
|
||||||
import Database from '@ioc:Adonis/Lucid/Database';
|
import Database from '@ioc:Adonis/Lucid/Database';
|
||||||
import Config from '@ioc:Adonis/Core/Config';
|
import Config from '@ioc:Adonis/Core/Config';
|
||||||
|
import Dataset from './Dataset';
|
||||||
|
|
||||||
// export default interface IUser {
|
// export default interface IUser {
|
||||||
// id: number;
|
// id: number;
|
||||||
|
@ -22,82 +23,87 @@ const roleTable = Config.get('rolePermission.role_table', 'roles');
|
||||||
const userRoleTable = Config.get('rolePermission.user_role_table', 'link_accounts_roles');
|
const userRoleTable = Config.get('rolePermission.user_role_table', 'link_accounts_roles');
|
||||||
|
|
||||||
export default class User extends BaseModel {
|
export default class User extends BaseModel {
|
||||||
public static table = 'accounts';
|
public static table = 'accounts';
|
||||||
|
|
||||||
@column({ isPrimary: true })
|
@column({ isPrimary: true })
|
||||||
public id: number;
|
public id: number;
|
||||||
|
|
||||||
@column()
|
@column()
|
||||||
public login: string;
|
public login: string;
|
||||||
|
|
||||||
@column()
|
@column()
|
||||||
public email: string;
|
public email: string;
|
||||||
|
|
||||||
@column({ serializeAs: null })
|
@column({ serializeAs: null })
|
||||||
public password: string;
|
public password: string;
|
||||||
|
|
||||||
@column.dateTime({ autoCreate: true })
|
@column.dateTime({ autoCreate: true })
|
||||||
public createdAt: DateTime;
|
public createdAt: DateTime;
|
||||||
|
|
||||||
@column.dateTime({ autoCreate: true, autoUpdate: true })
|
@column.dateTime({ autoCreate: true, autoUpdate: true })
|
||||||
public updatedAt: DateTime;
|
public updatedAt: DateTime;
|
||||||
|
|
||||||
@beforeSave()
|
@beforeSave()
|
||||||
public static async hashPassword(user) {
|
public static async hashPassword(user) {
|
||||||
if (user.$dirty.password) {
|
if (user.$dirty.password) {
|
||||||
user.password = await Hash.make(user.password);
|
user.password = await Hash.make(user.password);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@manyToMany(() => Role, {
|
@manyToMany(() => Role, {
|
||||||
pivotForeignKey: 'account_id',
|
pivotForeignKey: 'account_id',
|
||||||
pivotRelatedForeignKey: 'role_id',
|
pivotRelatedForeignKey: 'role_id',
|
||||||
pivotTable: 'link_accounts_roles',
|
pivotTable: 'link_accounts_roles',
|
||||||
})
|
})
|
||||||
public roles: ManyToMany<typeof Role>;
|
public roles: ManyToMany<typeof Role>;
|
||||||
|
|
||||||
// https://github.com/adonisjs/core/discussions/1872#discussioncomment-132289
|
@hasMany(() => Dataset, {
|
||||||
public async getRoles(this: User): Promise<string[]> {
|
foreignKey: 'account_id',
|
||||||
const test = await this.related('roles').query();
|
})
|
||||||
return test.map((role) => role.name);
|
public datasets: HasMany<typeof Dataset>;
|
||||||
}
|
|
||||||
|
|
||||||
public async can(permissionNames: Array<string>): Promise<boolean> {
|
// https://github.com/adonisjs/core/discussions/1872#discussioncomment-132289
|
||||||
// const permissions = await this.getPermissions()
|
public async getRoles(this: User): Promise<string[]> {
|
||||||
// return Acl.check(expression, operand => _.includes(permissions, operand))
|
const test = await this.related('roles').query();
|
||||||
const hasPermission = await this.checkHasPermissions(this, permissionNames);
|
return test.map((role) => role.name);
|
||||||
return hasPermission;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private async checkHasPermissions(user: User, permissionNames: Array<string>): Promise<boolean> {
|
public async can(permissionNames: Array<string>): Promise<boolean> {
|
||||||
let permissionPlaceHolder = '(';
|
// const permissions = await this.getPermissions()
|
||||||
let placeholders = new Array(permissionNames.length).fill('?');
|
// return Acl.check(expression, operand => _.includes(permissions, operand))
|
||||||
permissionPlaceHolder += placeholders.join(',');
|
const hasPermission = await this.checkHasPermissions(this, permissionNames);
|
||||||
permissionPlaceHolder += ')';
|
return hasPermission;
|
||||||
|
}
|
||||||
|
|
||||||
let {
|
private async checkHasPermissions(user: User, permissionNames: Array<string>): Promise<boolean> {
|
||||||
rows: {
|
let permissionPlaceHolder = '(';
|
||||||
0: { permissioncount },
|
let placeholders = new Array(permissionNames.length).fill('?');
|
||||||
},
|
permissionPlaceHolder += placeholders.join(',');
|
||||||
} = await Database.rawQuery(
|
permissionPlaceHolder += ')';
|
||||||
'SELECT count("p"."name") as permissionCount FROM ' +
|
|
||||||
roleTable +
|
|
||||||
' r INNER JOIN ' +
|
|
||||||
userRoleTable +
|
|
||||||
' ur ON ur.role_id=r.id AND "ur"."account_id"=? ' +
|
|
||||||
' INNER JOIN ' +
|
|
||||||
rolePermissionTable +
|
|
||||||
' rp ON rp.role_id=r.id ' +
|
|
||||||
' INNER JOIN ' +
|
|
||||||
permissionTable +
|
|
||||||
' p ON rp.permission_id=p.id AND "p"."name" in ' +
|
|
||||||
permissionPlaceHolder +
|
|
||||||
' LIMIT 1',
|
|
||||||
[user.id, ...permissionNames]
|
|
||||||
);
|
|
||||||
|
|
||||||
return permissioncount > 0;
|
let {
|
||||||
}
|
rows: {
|
||||||
|
0: { permissioncount },
|
||||||
|
},
|
||||||
|
} = await Database.rawQuery(
|
||||||
|
'SELECT count("p"."name") as permissionCount FROM ' +
|
||||||
|
roleTable +
|
||||||
|
' r INNER JOIN ' +
|
||||||
|
userRoleTable +
|
||||||
|
' ur ON ur.role_id=r.id AND "ur"."account_id"=? ' +
|
||||||
|
' INNER JOIN ' +
|
||||||
|
rolePermissionTable +
|
||||||
|
' rp ON rp.role_id=r.id ' +
|
||||||
|
' INNER JOIN ' +
|
||||||
|
permissionTable +
|
||||||
|
' p ON rp.permission_id=p.id AND "p"."name" in ' +
|
||||||
|
permissionPlaceHolder +
|
||||||
|
' LIMIT 1',
|
||||||
|
[user.id, ...permissionNames],
|
||||||
|
);
|
||||||
|
|
||||||
|
return permissioncount > 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// export default User;
|
// export default User;
|
||||||
|
|
|
@ -1,74 +1,74 @@
|
||||||
import {column, BaseModel, belongsTo, BelongsTo, SnakeCaseNamingStrategy} from '@ioc:Adonis/Lucid/Orm'
|
import { column, BaseModel, belongsTo, BelongsTo, SnakeCaseNamingStrategy } from '@ioc:Adonis/Lucid/Orm';
|
||||||
|
|
||||||
import User from 'App/Models/User'
|
import User from 'App/Models/User';
|
||||||
import Role from 'App/Models/Role'
|
import Role from 'App/Models/Role';
|
||||||
import { DateTime } from 'luxon'
|
import { DateTime } from 'luxon';
|
||||||
// import moment from 'moment'
|
// import moment from 'moment'
|
||||||
|
|
||||||
export default class UserRole extends BaseModel {
|
export default class UserRole extends BaseModel {
|
||||||
public static namingStrategy = new SnakeCaseNamingStrategy()
|
public static namingStrategy = new SnakeCaseNamingStrategy();
|
||||||
public static primaryKey = 'id'
|
public static primaryKey = 'id';
|
||||||
public static table = 'user_roles'
|
public static table = 'user_roles';
|
||||||
public static selfAssignPrimaryKey = false
|
public static selfAssignPrimaryKey = false;
|
||||||
|
|
||||||
@column({
|
@column({
|
||||||
isPrimary: true,
|
isPrimary: true,
|
||||||
})
|
|
||||||
public id: number
|
|
||||||
|
|
||||||
@column({})
|
|
||||||
public user_id: number
|
|
||||||
|
|
||||||
@column({})
|
|
||||||
public role_id: number
|
|
||||||
|
|
||||||
@column({
|
|
||||||
// serialize: (value: DateTime | null) => {
|
|
||||||
// return value ? moment(value).format('lll') : value
|
|
||||||
// },
|
|
||||||
})
|
|
||||||
public created_at: DateTime
|
|
||||||
|
|
||||||
@column({
|
|
||||||
// serialize: (value: DateTime | null) => {
|
|
||||||
// return value ? moment(value).format('lll') : value
|
|
||||||
// },
|
|
||||||
})
|
|
||||||
public updated_at: DateTime
|
|
||||||
|
|
||||||
public static boot() {
|
|
||||||
super.boot()
|
|
||||||
|
|
||||||
this.before('create', async (_modelInstance) => {
|
|
||||||
_modelInstance.created_at = this.formatDateTime(_modelInstance.created_at)
|
|
||||||
_modelInstance.updated_at = this.formatDateTime(_modelInstance.updated_at)
|
|
||||||
})
|
})
|
||||||
this.before('update', async (_modelInstance) => {
|
public id: number;
|
||||||
_modelInstance.created_at = this.formatDateTime(_modelInstance.created_at)
|
|
||||||
_modelInstance.updated_at = this.formatDateTime(_modelInstance.updated_at)
|
@column({})
|
||||||
|
public user_id: number;
|
||||||
|
|
||||||
|
@column({})
|
||||||
|
public role_id: number;
|
||||||
|
|
||||||
|
@column({
|
||||||
|
// serialize: (value: DateTime | null) => {
|
||||||
|
// return value ? moment(value).format('lll') : value
|
||||||
|
// },
|
||||||
})
|
})
|
||||||
}
|
public created_at: DateTime;
|
||||||
|
|
||||||
private static formatDateTime(datetime) {
|
@column({
|
||||||
let value = new Date(datetime)
|
// serialize: (value: DateTime | null) => {
|
||||||
return datetime
|
// return value ? moment(value).format('lll') : value
|
||||||
? value.getFullYear() +
|
// },
|
||||||
'-' +
|
})
|
||||||
(value.getMonth() + 1) +
|
public updated_at: DateTime;
|
||||||
'-' +
|
|
||||||
value.getDate() +
|
|
||||||
' ' +
|
|
||||||
value.getHours() +
|
|
||||||
':' +
|
|
||||||
value.getMinutes() +
|
|
||||||
':' +
|
|
||||||
value.getSeconds()
|
|
||||||
: datetime
|
|
||||||
}
|
|
||||||
|
|
||||||
@belongsTo(() => User)
|
public static boot() {
|
||||||
public user: BelongsTo<typeof User>
|
super.boot();
|
||||||
|
|
||||||
@belongsTo(() => Role)
|
this.before('create', async (_modelInstance) => {
|
||||||
public role: BelongsTo<typeof Role>
|
_modelInstance.created_at = this.formatDateTime(_modelInstance.created_at);
|
||||||
|
_modelInstance.updated_at = this.formatDateTime(_modelInstance.updated_at);
|
||||||
|
});
|
||||||
|
this.before('update', async (_modelInstance) => {
|
||||||
|
_modelInstance.created_at = this.formatDateTime(_modelInstance.created_at);
|
||||||
|
_modelInstance.updated_at = this.formatDateTime(_modelInstance.updated_at);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private static formatDateTime(datetime) {
|
||||||
|
let value = new Date(datetime);
|
||||||
|
return datetime
|
||||||
|
? value.getFullYear() +
|
||||||
|
'-' +
|
||||||
|
(value.getMonth() + 1) +
|
||||||
|
'-' +
|
||||||
|
value.getDate() +
|
||||||
|
' ' +
|
||||||
|
value.getHours() +
|
||||||
|
':' +
|
||||||
|
value.getMinutes() +
|
||||||
|
':' +
|
||||||
|
value.getSeconds()
|
||||||
|
: datetime;
|
||||||
|
}
|
||||||
|
|
||||||
|
@belongsTo(() => User)
|
||||||
|
public user: BelongsTo<typeof User>;
|
||||||
|
|
||||||
|
@belongsTo(() => Role)
|
||||||
|
public role: BelongsTo<typeof Role>;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,45 +2,45 @@ import { schema, CustomMessages, rules } from '@ioc:Adonis/Core/Validator';
|
||||||
import type { HttpContextContract } from '@ioc:Adonis/Core/HttpContext';
|
import type { HttpContextContract } from '@ioc:Adonis/Core/HttpContext';
|
||||||
|
|
||||||
export default class AuthValidator {
|
export default class AuthValidator {
|
||||||
constructor(protected ctx: HttpContextContract) {}
|
constructor(protected ctx: HttpContextContract) {}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Define schema to validate the "shape", "type", "formatting" and "integrity" of data.
|
* Define schema to validate the "shape", "type", "formatting" and "integrity" of data.
|
||||||
*
|
*
|
||||||
* For example:
|
* For example:
|
||||||
* 1. The username must be of data type string. But then also, it should
|
* 1. The username must be of data type string. But then also, it should
|
||||||
* not contain special characters or numbers.
|
* not contain special characters or numbers.
|
||||||
* ```
|
* ```
|
||||||
* schema.string({}, [ rules.alpha() ])
|
* schema.string({}, [ rules.alpha() ])
|
||||||
* ```
|
* ```
|
||||||
*
|
*
|
||||||
* 2. The email must be of data type string, formatted as a valid
|
* 2. The email must be of data type string, formatted as a valid
|
||||||
* email. But also, not used by any other user.
|
* email. But also, not used by any other user.
|
||||||
* ```
|
* ```
|
||||||
* schema.string({}, [
|
* schema.string({}, [
|
||||||
* rules.email(),
|
* rules.email(),
|
||||||
* rules.unique({ table: 'users', column: 'email' }),
|
* rules.unique({ table: 'users', column: 'email' }),
|
||||||
* ])
|
* ])
|
||||||
* ```
|
* ```
|
||||||
*/
|
*/
|
||||||
public schema = schema.create({
|
public schema = schema.create({
|
||||||
email: schema.string({ trim: true }, [
|
email: schema.string({ trim: true }, [
|
||||||
rules.email(),
|
rules.email(),
|
||||||
// rules.unique({ table: 'accounts', column: 'email' })
|
// rules.unique({ table: 'accounts', column: 'email' })
|
||||||
]),
|
]),
|
||||||
password: schema.string({}, [rules.minLength(6)]),
|
password: schema.string({}, [rules.minLength(6)]),
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Custom messages for validation failures. You can make use of dot notation `(.)`
|
* Custom messages for validation failures. You can make use of dot notation `(.)`
|
||||||
* for targeting nested fields and array expressions `(*)` for targeting all
|
* for targeting nested fields and array expressions `(*)` for targeting all
|
||||||
* children of an array. For example:
|
* children of an array. For example:
|
||||||
*
|
*
|
||||||
* {
|
* {
|
||||||
* 'profile.username.required': 'Username is required',
|
* 'profile.username.required': 'Username is required',
|
||||||
* 'scores.*.number': 'Define scores as valid numbers'
|
* 'scores.*.number': 'Define scores as valid numbers'
|
||||||
* }
|
* }
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public messages: CustomMessages = {};
|
public messages: CustomMessages = {};
|
||||||
}
|
}
|
||||||
|
|
157
app/Validators/CreateDatasetValidator.ts
Normal file
157
app/Validators/CreateDatasetValidator.ts
Normal file
|
@ -0,0 +1,157 @@
|
||||||
|
import { schema, CustomMessages, rules } from '@ioc:Adonis/Core/Validator';
|
||||||
|
import type { HttpContextContract } from '@ioc:Adonis/Core/HttpContext';
|
||||||
|
import dayjs from 'dayjs';
|
||||||
|
import { TitleTypes, DescriptionTypes } from 'Contracts/enums';
|
||||||
|
|
||||||
|
export default class CreateDatasetValidator {
|
||||||
|
constructor(protected ctx: HttpContextContract) {}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Define schema to validate the "shape", "type", "formatting" and "integrity" of data.
|
||||||
|
*
|
||||||
|
* For example:
|
||||||
|
* 1. The username must be of data type string. But then also, it should
|
||||||
|
* not contain special characters or numbers.
|
||||||
|
* ```
|
||||||
|
* schema.string({}, [ rules.alpha() ])
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* 2. The email must be of data type string, formatted as a valid
|
||||||
|
* email. But also, not used by any other user.
|
||||||
|
* ```
|
||||||
|
* schema.string({}, [
|
||||||
|
* rules.email(),
|
||||||
|
* rules.unique({ table: 'users', column: 'email' }),
|
||||||
|
* ])
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
public schema = schema.create({
|
||||||
|
// first step
|
||||||
|
language: schema.string({ trim: true }, [
|
||||||
|
rules.regex(/^[a-zA-Z0-9-_]+$/), //Must be alphanumeric with hyphens or underscores
|
||||||
|
]),
|
||||||
|
licenses: schema.array([rules.minLength(1)]).members(schema.number()), // define at least one license for the new dataset
|
||||||
|
rights: schema.string([rules.equalTo('true')]),
|
||||||
|
// second step
|
||||||
|
type: schema.string({ trim: true }, [rules.minLength(3), rules.maxLength(255)]),
|
||||||
|
creating_corporation: schema.string({ trim: true }, [rules.minLength(3), rules.maxLength(255)]),
|
||||||
|
titles: schema.array([rules.minLength(1)]).members(
|
||||||
|
schema.object().members({
|
||||||
|
value: schema.string({ trim: true }, [rules.minLength(3), rules.maxLength(255)]),
|
||||||
|
type: schema.enum(Object.values(TitleTypes)),
|
||||||
|
language: schema.string({ trim: true }, [
|
||||||
|
rules.minLength(2),
|
||||||
|
rules.maxLength(255),
|
||||||
|
rules.translatedLanguage('/language', 'type'),
|
||||||
|
]),
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
descriptions: schema.array([rules.minLength(1)]).members(
|
||||||
|
schema.object().members({
|
||||||
|
value: schema.string({ trim: true }, [rules.minLength(3), rules.maxLength(255)]),
|
||||||
|
type: schema.enum(Object.values(DescriptionTypes)),
|
||||||
|
language: schema.string({ trim: true }, [
|
||||||
|
rules.minLength(2),
|
||||||
|
rules.maxLength(255),
|
||||||
|
rules.translatedLanguage('/language', 'type'),
|
||||||
|
]),
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
authors: schema.array([rules.minLength(1)]).members(schema.object().members({ email: schema.string({ trim: true }) })),
|
||||||
|
// third step
|
||||||
|
project_id: schema.number.optional(),
|
||||||
|
embargo_date: schema.date.optional({ format: 'yyyy-MM-dd' }, [rules.after(10, 'days')]),
|
||||||
|
coverage: schema.object().members({
|
||||||
|
x_min: schema.number(),
|
||||||
|
x_max: schema.number(),
|
||||||
|
y_min: schema.number(),
|
||||||
|
y_max: schema.number(),
|
||||||
|
elevation_absolut: schema.number.optional(),
|
||||||
|
elevation_min: schema.number.optional([rules.requiredIfExists('elevation_max')]),
|
||||||
|
elevation_max: schema.number.optional([rules.requiredIfExists('elevation_min')]),
|
||||||
|
depth_absolut: schema.number.optional(),
|
||||||
|
depth_min: schema.number.optional([rules.requiredIfExists('depth_max')]),
|
||||||
|
depth_max: schema.number.optional([rules.requiredIfExists('depth_min')]),
|
||||||
|
}),
|
||||||
|
subjects: schema.array([rules.minLength(3), rules.uniqueArray('value')]).members(
|
||||||
|
schema.object().members({
|
||||||
|
value: schema.string({ trim: true }, [
|
||||||
|
rules.minLength(3),
|
||||||
|
rules.maxLength(255),
|
||||||
|
// rules.unique({ table: 'dataset_subjects', column: 'value' }),
|
||||||
|
]),
|
||||||
|
// type: schema.enum(Object.values(TitleTypes)),
|
||||||
|
language: schema.string({ trim: true }, [rules.minLength(2), rules.maxLength(255)]),
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
// file: schema.file({
|
||||||
|
// size: '100mb',
|
||||||
|
// extnames: ['jpg', 'gif', 'png'],
|
||||||
|
// }),
|
||||||
|
files: schema.array([rules.minLength(1)]).members(
|
||||||
|
schema.file({
|
||||||
|
size: '100mb',
|
||||||
|
extnames: ['jpg', 'gif', 'png'],
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
// upload: schema.object().members({
|
||||||
|
// label: schema.string({ trim: true }, [rules.maxLength(255)]),
|
||||||
|
|
||||||
|
// // label: schema.string({ trim: true }, [
|
||||||
|
// // // rules.minLength(3),
|
||||||
|
// // // rules.maxLength(255),
|
||||||
|
// // ]),
|
||||||
|
// }),
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Custom messages for validation failures. You can make use of dot notation `(.)`
|
||||||
|
* for targeting nested fields and array expressions `(*)` for targeting all
|
||||||
|
* children of an array. For example:
|
||||||
|
*
|
||||||
|
* {
|
||||||
|
* 'profile.username.required': 'Username is required',
|
||||||
|
* 'scores.*.number': 'Define scores as valid numbers'
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public messages: CustomMessages = {
|
||||||
|
'minLength': '{{ field }} must be at least {{ options.minLength }} characters long',
|
||||||
|
'maxLength': '{{ field }} must be less then {{ options.maxLength }} characters long',
|
||||||
|
'required': '{{ field }} is required',
|
||||||
|
'unique': '{{ field }} must be unique, and this value is already taken',
|
||||||
|
// 'confirmed': '{{ field }} is not correct',
|
||||||
|
'licences.minLength': 'at least {{ options.minLength }} permission must be defined',
|
||||||
|
'licences.*.number': 'Define roles as valid numbers',
|
||||||
|
'rights.equalTo': 'you must agree to continue',
|
||||||
|
|
||||||
|
'titles.0.value.minLength': 'Main Title must be at least {{ options.minLength }} characters long',
|
||||||
|
'titles.0.value.required': 'Main Title is required',
|
||||||
|
'titles.*.value.required': 'Additional title is required, if defined',
|
||||||
|
'titles.*.type.required': 'Additional title type is required',
|
||||||
|
'titles.*.language.required': 'Additional title language is required',
|
||||||
|
'titles.*.language.translatedLanguage': 'The language of the translated title must be different from the language of the dataset',
|
||||||
|
|
||||||
|
'descriptions.0.value.minLength': 'Main Abstract must be at least {{ options.minLength }} characters long',
|
||||||
|
'descriptions.0.value.required': 'Main Abstract is required',
|
||||||
|
'descriptions.*.value.required': 'Additional description is required, if defined',
|
||||||
|
'descriptions.*.type.required': 'Additional description type is required',
|
||||||
|
'descriptions.*.language.required': 'Additional description language is required',
|
||||||
|
'descriptions.*.language.translatedLanguage':
|
||||||
|
'The language of the translated description must be different from the language of the dataset',
|
||||||
|
|
||||||
|
'authors.minLength': 'at least {{ options.minLength }} author must be defined',
|
||||||
|
|
||||||
|
'after': `{{ field }} must be older than ${dayjs().add(10, 'day')}`,
|
||||||
|
|
||||||
|
'subjects.minLength': 'at least {{ options.minLength }} keywords must be defined',
|
||||||
|
'subjects.uniqueArray': 'The {{ options.array }} array must have unique values based on the {{ options.field }} attribute.',
|
||||||
|
'subjects.*.value.required': 'keyword value is required',
|
||||||
|
'subjects.*.value.minLength': 'keyword value must be at least {{ options.minLength }} characters long',
|
||||||
|
'subjects.*.type.required': 'keyword type is required',
|
||||||
|
'subjects.*.language.required': 'language of keyword is required',
|
||||||
|
|
||||||
|
'files.*.size': 'file size is to big',
|
||||||
|
'files.extnames': 'file extension is not supported',
|
||||||
|
};
|
||||||
|
}
|
|
@ -2,68 +2,68 @@ import { schema, CustomMessages, rules } from '@ioc:Adonis/Core/Validator';
|
||||||
import type { HttpContextContract } from '@ioc:Adonis/Core/HttpContext';
|
import type { HttpContextContract } from '@ioc:Adonis/Core/HttpContext';
|
||||||
|
|
||||||
export default class CreateRoleValidator {
|
export default class CreateRoleValidator {
|
||||||
constructor(protected ctx: HttpContextContract) {}
|
constructor(protected ctx: HttpContextContract) {}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Define schema to validate the "shape", "type", "formatting" and "integrity" of data.
|
* Define schema to validate the "shape", "type", "formatting" and "integrity" of data.
|
||||||
*
|
*
|
||||||
* For example:
|
* For example:
|
||||||
* 1. The username must be of data type string. But then also, it should
|
* 1. The username must be of data type string. But then also, it should
|
||||||
* not contain special characters or numbers.
|
* not contain special characters or numbers.
|
||||||
* ```
|
* ```
|
||||||
* schema.string({}, [ rules.alpha() ])
|
* schema.string({}, [ rules.alpha() ])
|
||||||
* ```
|
* ```
|
||||||
*
|
*
|
||||||
* 2. The email must be of data type string, formatted as a valid
|
* 2. The email must be of data type string, formatted as a valid
|
||||||
* email. But also, not used by any other user.
|
* email. But also, not used by any other user.
|
||||||
* ```
|
* ```
|
||||||
* schema.string({}, [
|
* schema.string({}, [
|
||||||
* rules.email(),
|
* rules.email(),
|
||||||
* rules.unique({ table: 'users', column: 'email' }),
|
* rules.unique({ table: 'users', column: 'email' }),
|
||||||
* ])
|
* ])
|
||||||
* ```
|
* ```
|
||||||
*/
|
*/
|
||||||
public schema = schema.create({
|
public schema = schema.create({
|
||||||
name: schema.string({ trim: true }, [
|
name: schema.string({ trim: true }, [
|
||||||
rules.minLength(3),
|
rules.minLength(3),
|
||||||
rules.maxLength(255),
|
rules.maxLength(255),
|
||||||
rules.unique({ table: 'roles', column: 'name' }),
|
rules.unique({ table: 'roles', column: 'name' }),
|
||||||
rules.regex(/^[a-zA-Z0-9-_]+$/), //Must be alphanumeric with hyphens or underscores
|
rules.regex(/^[a-zA-Z0-9-_]+$/), //Must be alphanumeric with hyphens or underscores
|
||||||
]),
|
]),
|
||||||
display_name: schema.string.optional({ trim: true }, [
|
display_name: schema.string.optional({ trim: true }, [
|
||||||
rules.minLength(3),
|
rules.minLength(3),
|
||||||
rules.maxLength(255),
|
rules.maxLength(255),
|
||||||
rules.unique({ table: 'roles', column: 'name' }),
|
rules.unique({ table: 'roles', column: 'name' }),
|
||||||
rules.regex(/^[a-zA-Z0-9-_]+$/), //Must be alphanumeric with hyphens or underscores
|
rules.regex(/^[a-zA-Z0-9-_]+$/), //Must be alphanumeric with hyphens or underscores
|
||||||
]),
|
]),
|
||||||
description: schema.string.optional({}, [rules.minLength(3), rules.maxLength(255)]),
|
description: schema.string.optional({}, [rules.minLength(3), rules.maxLength(255)]),
|
||||||
permissions: schema.array([rules.minLength(1)]).members(schema.number()), // define at least one role for the new role
|
permissions: schema.array([rules.minLength(1)]).members(schema.number()), // define at least one role for the new role
|
||||||
});
|
});
|
||||||
|
|
||||||
// emails: schema
|
// emails: schema
|
||||||
// .array([rules.minLength(1)])
|
// .array([rules.minLength(1)])
|
||||||
// .members(
|
// .members(
|
||||||
// schema.object().members({ email: schema.string({}, [rules.email()]) })
|
// schema.object().members({ email: schema.string({}, [rules.email()]) })
|
||||||
// ),
|
// ),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Custom messages for validation failures. You can make use of dot notation `(.)`
|
* Custom messages for validation failures. You can make use of dot notation `(.)`
|
||||||
* for targeting nested fields and array expressions `(*)` for targeting all
|
* for targeting nested fields and array expressions `(*)` for targeting all
|
||||||
* children of an array. For example:
|
* children of an array. For example:
|
||||||
*
|
*
|
||||||
* {
|
* {
|
||||||
* 'profile.username.required': 'Username is required',
|
* 'profile.username.required': 'Username is required',
|
||||||
* 'scores.*.number': 'Define scores as valid numbers'
|
* 'scores.*.number': 'Define scores as valid numbers'
|
||||||
* }
|
* }
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public messages: CustomMessages = {
|
public messages: CustomMessages = {
|
||||||
'minLength': '{{ field }} must be at least {{ options.minLength }} characters long',
|
'minLength': '{{ field }} must be at least {{ options.minLength }} characters long',
|
||||||
'maxLength': '{{ field }} must be less then {{ options.maxLength }} characters long',
|
'maxLength': '{{ field }} must be less then {{ options.maxLength }} characters long',
|
||||||
'required': '{{ field }} is required',
|
'required': '{{ field }} is required',
|
||||||
'unique': '{{ field }} must be unique, and this value is already taken',
|
'unique': '{{ field }} must be unique, and this value is already taken',
|
||||||
'confirmed': '{{ field }} is not correct',
|
'confirmed': '{{ field }} is not correct',
|
||||||
'permissions.minLength': 'at least {{ options.minLength }} permission must be defined',
|
'permissions.minLength': 'at least {{ options.minLength }} permission must be defined',
|
||||||
'permissions.*.number': 'Define roles as valid numbers',
|
'permissions.*.number': 'Define roles as valid numbers',
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,63 +2,63 @@ import { schema, CustomMessages, rules } from '@ioc:Adonis/Core/Validator';
|
||||||
import type { HttpContextContract } from '@ioc:Adonis/Core/HttpContext';
|
import type { HttpContextContract } from '@ioc:Adonis/Core/HttpContext';
|
||||||
|
|
||||||
export default class CreateUserValidator {
|
export default class CreateUserValidator {
|
||||||
constructor(protected ctx: HttpContextContract) {}
|
constructor(protected ctx: HttpContextContract) {}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Define schema to validate the "shape", "type", "formatting" and "integrity" of data.
|
* Define schema to validate the "shape", "type", "formatting" and "integrity" of data.
|
||||||
*
|
*
|
||||||
* For example:
|
* For example:
|
||||||
* 1. The username must be of data type string. But then also, it should
|
* 1. The username must be of data type string. But then also, it should
|
||||||
* not contain special characters or numbers.
|
* not contain special characters or numbers.
|
||||||
* ```
|
* ```
|
||||||
* schema.string({}, [ rules.alpha() ])
|
* schema.string({}, [ rules.alpha() ])
|
||||||
* ```
|
* ```
|
||||||
*
|
*
|
||||||
* 2. The email must be of data type string, formatted as a valid
|
* 2. The email must be of data type string, formatted as a valid
|
||||||
* email. But also, not used by any other user.
|
* email. But also, not used by any other user.
|
||||||
* ```
|
* ```
|
||||||
* schema.string({}, [
|
* schema.string({}, [
|
||||||
* rules.email(),
|
* rules.email(),
|
||||||
* rules.unique({ table: 'users', column: 'email' }),
|
* rules.unique({ table: 'users', column: 'email' }),
|
||||||
* ])
|
* ])
|
||||||
* ```
|
* ```
|
||||||
*/
|
*/
|
||||||
public schema = schema.create({
|
public schema = schema.create({
|
||||||
login: schema.string({ trim: true }, [
|
login: schema.string({ trim: true }, [
|
||||||
rules.minLength(3),
|
rules.minLength(3),
|
||||||
rules.maxLength(50),
|
rules.maxLength(50),
|
||||||
rules.unique({ table: 'accounts', column: 'login' }),
|
rules.unique({ table: 'accounts', column: 'login' }),
|
||||||
rules.regex(/^[a-zA-Z0-9-_]+$/), //Must be alphanumeric with hyphens or underscores
|
rules.regex(/^[a-zA-Z0-9-_]+$/), //Must be alphanumeric with hyphens or underscores
|
||||||
]),
|
]),
|
||||||
email: schema.string({}, [rules.email(), rules.unique({ table: 'accounts', column: 'email' })]),
|
email: schema.string({}, [rules.email(), rules.unique({ table: 'accounts', column: 'email' })]),
|
||||||
password: schema.string([rules.confirmed(), rules.minLength(6)]),
|
password: schema.string([rules.confirmed(), rules.minLength(6)]),
|
||||||
roles: schema.array([rules.minLength(1)]).members(schema.number()), // define at least one role for the new user
|
roles: schema.array([rules.minLength(1)]).members(schema.number()), // define at least one role for the new user
|
||||||
});
|
});
|
||||||
|
|
||||||
// emails: schema
|
// emails: schema
|
||||||
// .array([rules.minLength(1)])
|
// .array([rules.minLength(1)])
|
||||||
// .members(
|
// .members(
|
||||||
// schema.object().members({ email: schema.string({}, [rules.email()]) })
|
// schema.object().members({ email: schema.string({}, [rules.email()]) })
|
||||||
// ),
|
// ),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Custom messages for validation failures. You can make use of dot notation `(.)`
|
* Custom messages for validation failures. You can make use of dot notation `(.)`
|
||||||
* for targeting nested fields and array expressions `(*)` for targeting all
|
* for targeting nested fields and array expressions `(*)` for targeting all
|
||||||
* children of an array. For example:
|
* children of an array. For example:
|
||||||
*
|
*
|
||||||
* {
|
* {
|
||||||
* 'profile.username.required': 'Username is required',
|
* 'profile.username.required': 'Username is required',
|
||||||
* 'scores.*.number': 'Define scores as valid numbers'
|
* 'scores.*.number': 'Define scores as valid numbers'
|
||||||
* }
|
* }
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public messages: CustomMessages = {
|
public messages: CustomMessages = {
|
||||||
'minLength': '{{ field }} must be at least {{ options.minLength }} characters long',
|
'minLength': '{{ field }} must be at least {{ options.minLength }} characters long',
|
||||||
'maxLength': '{{ field }} must be less then {{ options.maxLength }} characters long',
|
'maxLength': '{{ field }} must be less then {{ options.maxLength }} characters long',
|
||||||
'required': '{{ field }} is required',
|
'required': '{{ field }} is required',
|
||||||
'unique': '{{ field }} must be unique, and this value is already taken',
|
'unique': '{{ field }} must be unique, and this value is already taken',
|
||||||
'confirmed': '{{ field }} is not correct',
|
'confirmed': '{{ field }} is not correct',
|
||||||
'roles.minLength': 'at least {{ options.minLength }} role must be defined',
|
'roles.minLength': 'at least {{ options.minLength }} role must be defined',
|
||||||
'roles.*.number': 'Define roles as valid numbers'
|
'roles.*.number': 'Define roles as valid numbers',
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,95 +3,95 @@ import type { HttpContextContract } from '@ioc:Adonis/Core/HttpContext';
|
||||||
// import { Request } from '@adonisjs/core/build/standalone';
|
// import { Request } from '@adonisjs/core/build/standalone';
|
||||||
|
|
||||||
export default class UpdateRoleValidator {
|
export default class UpdateRoleValidator {
|
||||||
protected ctx: HttpContextContract;
|
protected ctx: HttpContextContract;
|
||||||
public schema;
|
public schema;
|
||||||
|
|
||||||
constructor(ctx: HttpContextContract) {
|
constructor(ctx: HttpContextContract) {
|
||||||
this.ctx = ctx;
|
this.ctx = ctx;
|
||||||
this.schema = this.createSchema();
|
this.schema = this.createSchema();
|
||||||
}
|
}
|
||||||
|
|
||||||
// public get schema() {
|
// public get schema() {
|
||||||
// return this._schema;
|
// return this._schema;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
private createSchema() {
|
private createSchema() {
|
||||||
return schema.create({
|
return schema.create({
|
||||||
name: schema.string({ trim: true }, [
|
name: schema.string({ trim: true }, [
|
||||||
rules.minLength(3),
|
rules.minLength(3),
|
||||||
rules.maxLength(50),
|
rules.maxLength(50),
|
||||||
rules.unique({
|
rules.unique({
|
||||||
table: 'roles',
|
table: 'roles',
|
||||||
column: 'name',
|
column: 'name',
|
||||||
whereNot: { id: this.ctx?.params.id },
|
whereNot: { id: this.ctx?.params.id },
|
||||||
}),
|
}),
|
||||||
rules.regex(/^[a-zA-Z0-9-_]+$/),
|
rules.regex(/^[a-zA-Z0-9-_]+$/),
|
||||||
//Must be alphanumeric with hyphens or underscores
|
//Must be alphanumeric with hyphens or underscores
|
||||||
]),
|
]),
|
||||||
description: schema.string.optional({}, [rules.minLength(3), rules.maxLength(255)]),
|
description: schema.string.optional({}, [rules.minLength(3), rules.maxLength(255)]),
|
||||||
permissions: schema.array([rules.minLength(1)]).members(schema.number()), // define at least one permission for the new role
|
permissions: schema.array([rules.minLength(1)]).members(schema.number()), // define at least one permission for the new role
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Define schema to validate the "shape", "type", "formatting" and "integrity" of data.
|
* Define schema to validate the "shape", "type", "formatting" and "integrity" of data.
|
||||||
*
|
*
|
||||||
* For example:
|
* For example:
|
||||||
* 1. The username must be of data type string. But then also, it should
|
* 1. The username must be of data type string. But then also, it should
|
||||||
* not contain special characters or numbers.
|
* not contain special characters or numbers.
|
||||||
* ```
|
* ```
|
||||||
* schema.string({}, [ rules.alpha() ])
|
* schema.string({}, [ rules.alpha() ])
|
||||||
* ```
|
* ```
|
||||||
*
|
*
|
||||||
* 2. The email must be of data type string, formatted as a valid
|
* 2. The email must be of data type string, formatted as a valid
|
||||||
* email. But also, not used by any other user.
|
* email. But also, not used by any other user.
|
||||||
* ```
|
* ```
|
||||||
* schema.string({}, [
|
* schema.string({}, [
|
||||||
* rules.email(),
|
* rules.email(),
|
||||||
* rules.unique({ table: 'users', column: 'email' }),
|
* rules.unique({ table: 'users', column: 'email' }),
|
||||||
* ])
|
* ])
|
||||||
* ```
|
* ```
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// public refs = schema.refs({
|
// public refs = schema.refs({
|
||||||
// id: this.ctx.params.id
|
// id: this.ctx.params.id
|
||||||
// })
|
// })
|
||||||
|
|
||||||
// public schema = schema.create({
|
// public schema = schema.create({
|
||||||
// login: schema.string({ trim: true }, [
|
// login: schema.string({ trim: true }, [
|
||||||
// rules.minLength(3),
|
// rules.minLength(3),
|
||||||
// rules.maxLength(50),
|
// rules.maxLength(50),
|
||||||
// rules.unique({
|
// rules.unique({
|
||||||
// table: 'accounts',
|
// table: 'accounts',
|
||||||
// column: 'login',
|
// column: 'login',
|
||||||
// // whereNot: { id: this.refs.id }
|
// // whereNot: { id: this.refs.id }
|
||||||
// whereNot: { id: this.ctx?.params.id },
|
// whereNot: { id: this.ctx?.params.id },
|
||||||
// }),
|
// }),
|
||||||
// // rules.regex(/^[a-zA-Z0-9-_]+$/),
|
// // rules.regex(/^[a-zA-Z0-9-_]+$/),
|
||||||
// //Must be alphanumeric with hyphens or underscores
|
// //Must be alphanumeric with hyphens or underscores
|
||||||
// ]),
|
// ]),
|
||||||
// email: schema.string({}, [rules.email(), rules.unique({ table: 'accounts', column: 'email' })]),
|
// email: schema.string({}, [rules.email(), rules.unique({ table: 'accounts', column: 'email' })]),
|
||||||
// password: schema.string.optional([rules.confirmed(), rules.minLength(6)]),
|
// password: schema.string.optional([rules.confirmed(), rules.minLength(6)]),
|
||||||
// roles: schema.array([rules.minLength(1)]).members(schema.number()), // define at least one role for the new user
|
// roles: schema.array([rules.minLength(1)]).members(schema.number()), // define at least one role for the new user
|
||||||
// });
|
// });
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Custom messages for validation failures. You can make use of dot notation `(.)`
|
* Custom messages for validation failures. You can make use of dot notation `(.)`
|
||||||
* for targeting nested fields and array expressions `(*)` for targeting all
|
* for targeting nested fields and array expressions `(*)` for targeting all
|
||||||
* children of an array. For example:
|
* children of an array. For example:
|
||||||
*
|
*
|
||||||
* {
|
* {
|
||||||
* 'profile.username.required': 'Username is required',
|
* 'profile.username.required': 'Username is required',
|
||||||
* 'scores.*.number': 'Define scores as valid numbers'
|
* 'scores.*.number': 'Define scores as valid numbers'
|
||||||
* }
|
* }
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public messages: CustomMessages = {
|
public messages: CustomMessages = {
|
||||||
'minLength': '{{ field }} must be at least {{ options.minLength }} characters long',
|
'minLength': '{{ field }} must be at least {{ options.minLength }} characters long',
|
||||||
'maxLength': '{{ field }} must be less then {{ options.maxLength }} characters long',
|
'maxLength': '{{ field }} must be less then {{ options.maxLength }} characters long',
|
||||||
'required': '{{ field }} is required',
|
'required': '{{ field }} is required',
|
||||||
'unique': '{{ field }} must be unique, and this value is already taken',
|
'unique': '{{ field }} must be unique, and this value is already taken',
|
||||||
'permissions.minLength': 'at least {{ options.minLength }} permission must be defined',
|
'permissions.minLength': 'at least {{ options.minLength }} permission must be defined',
|
||||||
'permissions.*.number': 'Define permissions as valid numbers',
|
'permissions.*.number': 'Define permissions as valid numbers',
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
declare module '@ioc:Adonis/Core/Validator' {
|
declare module '@ioc:Adonis/Core/Validator' {
|
||||||
interface Rules {
|
interface Rules {
|
||||||
translatedLanguage(mainLanguageField: string, typeField: string): Rule;
|
translatedLanguage(mainLanguageField: string, typeField: string): Rule;
|
||||||
|
uniqueArray(field: string): Rule;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@ export default class DatasetTitles extends BaseSchema {
|
||||||
.foreign('document_id', 'dataset_titles_document_id_foreign')
|
.foreign('document_id', 'dataset_titles_document_id_foreign')
|
||||||
.references('id')
|
.references('id')
|
||||||
.inTable('documents')
|
.inTable('documents')
|
||||||
.onDelete('CASCADE') // delete this titke when document is deleted
|
.onDelete('CASCADE') // delete this title when document is deleted
|
||||||
.onUpdate('CASCADE');
|
.onUpdate('CASCADE');
|
||||||
// table.string('type', 255).notNullable();
|
// table.string('type', 255).notNullable();
|
||||||
table.enum('type', Object.values(TitleTypes)).notNullable();
|
table.enum('type', Object.values(TitleTypes)).notNullable();
|
||||||
|
|
|
@ -20,6 +20,7 @@ export default class Persons extends BaseSchema {
|
||||||
table.integer('registered_at');
|
table.integer('registered_at');
|
||||||
// table.string('name_type', 255);
|
// table.string('name_type', 255);
|
||||||
table.enum('name_type', Object.values(PersonNameTypes)).notNullable();
|
table.enum('name_type', Object.values(PersonNameTypes)).notNullable();
|
||||||
|
table.timestamp('created_at', { useTz: false }).nullable();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
8
index.d.ts
vendored
8
index.d.ts
vendored
|
@ -1,5 +1,5 @@
|
||||||
declare module '*.vue' {
|
declare module '*.vue' {
|
||||||
import type { DefineComponent } from "vue"
|
import type { DefineComponent } from 'vue';
|
||||||
const component: DefineComponent<{}, {}, any>
|
const component: DefineComponent<{}, {}, any>;
|
||||||
export default component
|
export default component;
|
||||||
}
|
}
|
||||||
|
|
166
package-lock.json
generated
166
package-lock.json
generated
|
@ -9,7 +9,7 @@
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@adonisjs/auth": "^8.2.3",
|
"@adonisjs/auth": "^8.2.3",
|
||||||
"@adonisjs/core": "^5.8.3",
|
"@adonisjs/core": "^5.9.0",
|
||||||
"@adonisjs/lucid": "^18.3.0",
|
"@adonisjs/lucid": "^18.3.0",
|
||||||
"@adonisjs/repl": "^3.1.11",
|
"@adonisjs/repl": "^3.1.11",
|
||||||
"@adonisjs/session": "^6.4.0",
|
"@adonisjs/session": "^6.4.0",
|
||||||
|
@ -571,9 +571,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@adonisjs/shield": {
|
"node_modules/@adonisjs/shield": {
|
||||||
"version": "7.1.0",
|
"version": "7.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/@adonisjs/shield/-/shield-7.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@adonisjs/shield/-/shield-7.1.1.tgz",
|
||||||
"integrity": "sha512-+a4Z+LBcWd46gMh99Wf0+iJMowq4aKuD04kvYB4AgTV78ffn21AXq3bsnoklFACkidEJwZ3FlRfQfKE+z1vg+g==",
|
"integrity": "sha512-y1YzXwravcS/A1yxcyfSD/UrRi2+H9v0ntX9NgVhLYvBF5eHuPzQKgv9sICVjmj2z7n94HzcTAio0Rc32EX51Q==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@poppinss/utils": "^4.0.4",
|
"@poppinss/utils": "^4.0.4",
|
||||||
"csrf": "^3.1.0",
|
"csrf": "^3.1.0",
|
||||||
|
@ -2765,9 +2765,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@eslint/js": {
|
"node_modules/@eslint/js": {
|
||||||
"version": "8.42.0",
|
"version": "8.43.0",
|
||||||
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.42.0.tgz",
|
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.43.0.tgz",
|
||||||
"integrity": "sha512-6SWlXpWU5AvId8Ac7zjzmIOqMOba/JWY8XZ4A7q7Gn1Vlfg/SFFIlrtHXt9nPn4op9ZPAkl91Jao+QQv3r/ukw==",
|
"integrity": "sha512-s2UHCoiXfxMvmfzqoN+vrQ84ahUSYde9qNO1MdxmoEhyHWsfmwOpFlwYV+ePJEVc7gFnATGUi376WowX1N7tFg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||||
|
@ -4094,15 +4094,15 @@
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/@typescript-eslint/eslint-plugin": {
|
"node_modules/@typescript-eslint/eslint-plugin": {
|
||||||
"version": "5.59.11",
|
"version": "5.60.0",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.59.11.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.60.0.tgz",
|
||||||
"integrity": "sha512-XxuOfTkCUiOSyBWIvHlUraLw/JT/6Io1365RO6ZuI88STKMavJZPNMU0lFcUTeQXEhHiv64CbxYxBNoDVSmghg==",
|
"integrity": "sha512-78B+anHLF1TI8Jn/cD0Q00TBYdMgjdOn980JfAVa9yw5sop8nyTfVOQAv6LWywkOGLclDBtv5z3oxN4w7jxyNg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@eslint-community/regexpp": "^4.4.0",
|
"@eslint-community/regexpp": "^4.4.0",
|
||||||
"@typescript-eslint/scope-manager": "5.59.11",
|
"@typescript-eslint/scope-manager": "5.60.0",
|
||||||
"@typescript-eslint/type-utils": "5.59.11",
|
"@typescript-eslint/type-utils": "5.60.0",
|
||||||
"@typescript-eslint/utils": "5.59.11",
|
"@typescript-eslint/utils": "5.60.0",
|
||||||
"debug": "^4.3.4",
|
"debug": "^4.3.4",
|
||||||
"grapheme-splitter": "^1.0.4",
|
"grapheme-splitter": "^1.0.4",
|
||||||
"ignore": "^5.2.0",
|
"ignore": "^5.2.0",
|
||||||
|
@ -4128,14 +4128,14 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typescript-eslint/parser": {
|
"node_modules/@typescript-eslint/parser": {
|
||||||
"version": "5.59.11",
|
"version": "5.60.0",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.59.11.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.60.0.tgz",
|
||||||
"integrity": "sha512-s9ZF3M+Nym6CAZEkJJeO2TFHHDsKAM3ecNkLuH4i4s8/RCPnF5JRip2GyviYkeEAcwGMJxkqG9h2dAsnA1nZpA==",
|
"integrity": "sha512-jBONcBsDJ9UoTWrARkRRCgDz6wUggmH5RpQVlt7BimSwaTkTjwypGzKORXbR4/2Hqjk9hgwlon2rVQAjWNpkyQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@typescript-eslint/scope-manager": "5.59.11",
|
"@typescript-eslint/scope-manager": "5.60.0",
|
||||||
"@typescript-eslint/types": "5.59.11",
|
"@typescript-eslint/types": "5.60.0",
|
||||||
"@typescript-eslint/typescript-estree": "5.59.11",
|
"@typescript-eslint/typescript-estree": "5.60.0",
|
||||||
"debug": "^4.3.4"
|
"debug": "^4.3.4"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
|
@ -4155,13 +4155,13 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typescript-eslint/scope-manager": {
|
"node_modules/@typescript-eslint/scope-manager": {
|
||||||
"version": "5.59.11",
|
"version": "5.60.0",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.11.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.60.0.tgz",
|
||||||
"integrity": "sha512-dHFOsxoLFtrIcSj5h0QoBT/89hxQONwmn3FOQ0GOQcLOOXm+MIrS8zEAhs4tWl5MraxCY3ZJpaXQQdFMc2Tu+Q==",
|
"integrity": "sha512-hakuzcxPwXi2ihf9WQu1BbRj1e/Pd8ZZwVTG9kfbxAMZstKz8/9OoexIwnmLzShtsdap5U/CoQGRCWlSuPbYxQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@typescript-eslint/types": "5.59.11",
|
"@typescript-eslint/types": "5.60.0",
|
||||||
"@typescript-eslint/visitor-keys": "5.59.11"
|
"@typescript-eslint/visitor-keys": "5.60.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||||
|
@ -4172,13 +4172,13 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typescript-eslint/type-utils": {
|
"node_modules/@typescript-eslint/type-utils": {
|
||||||
"version": "5.59.11",
|
"version": "5.60.0",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.59.11.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.60.0.tgz",
|
||||||
"integrity": "sha512-LZqVY8hMiVRF2a7/swmkStMYSoXMFlzL6sXV6U/2gL5cwnLWQgLEG8tjWPpaE4rMIdZ6VKWwcffPlo1jPfk43g==",
|
"integrity": "sha512-X7NsRQddORMYRFH7FWo6sA9Y/zbJ8s1x1RIAtnlj6YprbToTiQnM6vxcMu7iYhdunmoC0rUWlca13D5DVHkK2g==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@typescript-eslint/typescript-estree": "5.59.11",
|
"@typescript-eslint/typescript-estree": "5.60.0",
|
||||||
"@typescript-eslint/utils": "5.59.11",
|
"@typescript-eslint/utils": "5.60.0",
|
||||||
"debug": "^4.3.4",
|
"debug": "^4.3.4",
|
||||||
"tsutils": "^3.21.0"
|
"tsutils": "^3.21.0"
|
||||||
},
|
},
|
||||||
|
@ -4199,9 +4199,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typescript-eslint/types": {
|
"node_modules/@typescript-eslint/types": {
|
||||||
"version": "5.59.11",
|
"version": "5.60.0",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.11.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.60.0.tgz",
|
||||||
"integrity": "sha512-epoN6R6tkvBYSc+cllrz+c2sOFWkbisJZWkOE+y3xHtvYaOE6Wk6B8e114McRJwFRjGvYdJwLXQH5c9osME/AA==",
|
"integrity": "sha512-ascOuoCpNZBccFVNJRSC6rPq4EmJ2NkuoKnd6LDNyAQmdDnziAtxbCGWCbefG1CNzmDvd05zO36AmB7H8RzKPA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||||
|
@ -4212,13 +4212,13 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typescript-eslint/typescript-estree": {
|
"node_modules/@typescript-eslint/typescript-estree": {
|
||||||
"version": "5.59.11",
|
"version": "5.60.0",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.11.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.60.0.tgz",
|
||||||
"integrity": "sha512-YupOpot5hJO0maupJXixi6l5ETdrITxeo5eBOeuV7RSKgYdU3G5cxO49/9WRnJq9EMrB7AuTSLH/bqOsXi7wPA==",
|
"integrity": "sha512-R43thAuwarC99SnvrBmh26tc7F6sPa2B3evkXp/8q954kYL6Ro56AwASYWtEEi+4j09GbiNAHqYwNNZuNlARGQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@typescript-eslint/types": "5.59.11",
|
"@typescript-eslint/types": "5.60.0",
|
||||||
"@typescript-eslint/visitor-keys": "5.59.11",
|
"@typescript-eslint/visitor-keys": "5.60.0",
|
||||||
"debug": "^4.3.4",
|
"debug": "^4.3.4",
|
||||||
"globby": "^11.1.0",
|
"globby": "^11.1.0",
|
||||||
"is-glob": "^4.0.3",
|
"is-glob": "^4.0.3",
|
||||||
|
@ -4289,17 +4289,17 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typescript-eslint/utils": {
|
"node_modules/@typescript-eslint/utils": {
|
||||||
"version": "5.59.11",
|
"version": "5.60.0",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.59.11.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.60.0.tgz",
|
||||||
"integrity": "sha512-didu2rHSOMUdJThLk4aZ1Or8IcO3HzCw/ZvEjTTIfjIrcdd5cvSIwwDy2AOlE7htSNp7QIZ10fLMyRCveesMLg==",
|
"integrity": "sha512-ba51uMqDtfLQ5+xHtwlO84vkdjrqNzOnqrnwbMHMRY8Tqeme8C2Q8Fc7LajfGR+e3/4LoYiWXUM6BpIIbHJ4hQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@eslint-community/eslint-utils": "^4.2.0",
|
"@eslint-community/eslint-utils": "^4.2.0",
|
||||||
"@types/json-schema": "^7.0.9",
|
"@types/json-schema": "^7.0.9",
|
||||||
"@types/semver": "^7.3.12",
|
"@types/semver": "^7.3.12",
|
||||||
"@typescript-eslint/scope-manager": "5.59.11",
|
"@typescript-eslint/scope-manager": "5.60.0",
|
||||||
"@typescript-eslint/types": "5.59.11",
|
"@typescript-eslint/types": "5.60.0",
|
||||||
"@typescript-eslint/typescript-estree": "5.59.11",
|
"@typescript-eslint/typescript-estree": "5.60.0",
|
||||||
"eslint-scope": "^5.1.1",
|
"eslint-scope": "^5.1.1",
|
||||||
"semver": "^7.3.7"
|
"semver": "^7.3.7"
|
||||||
},
|
},
|
||||||
|
@ -4337,12 +4337,12 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typescript-eslint/visitor-keys": {
|
"node_modules/@typescript-eslint/visitor-keys": {
|
||||||
"version": "5.59.11",
|
"version": "5.60.0",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.11.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.60.0.tgz",
|
||||||
"integrity": "sha512-KGYniTGG3AMTuKF9QBD7EIrvufkB6O6uX3knP73xbKLMpH+QRPcgnCxjWXSHjMRuOxFLovljqQgQpR0c7GvjoA==",
|
"integrity": "sha512-wm9Uz71SbCyhUKgcaPRauBdTegUyY/ZWl8gLwD/i/ybJqscrrdVSFImpvUz16BLPChIeKBK5Fa9s6KDQjsjyWw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@typescript-eslint/types": "5.59.11",
|
"@typescript-eslint/types": "5.60.0",
|
||||||
"eslint-visitor-keys": "^3.3.0"
|
"eslint-visitor-keys": "^3.3.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
|
@ -4723,9 +4723,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/acorn": {
|
"node_modules/acorn": {
|
||||||
"version": "8.8.2",
|
"version": "8.9.0",
|
||||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz",
|
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.9.0.tgz",
|
||||||
"integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==",
|
"integrity": "sha512-jaVNAFBHNLXspO543WnNNPZFRtavh3skAkITqD0/2aeMkKZTN+254PyhwxFYrk3vQ1xfY+2wbesJMs/JC8/PwQ==",
|
||||||
"bin": {
|
"bin": {
|
||||||
"acorn": "bin/acorn"
|
"acorn": "bin/acorn"
|
||||||
},
|
},
|
||||||
|
@ -5741,9 +5741,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/browserslist": {
|
"node_modules/browserslist": {
|
||||||
"version": "4.21.8",
|
"version": "4.21.9",
|
||||||
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.8.tgz",
|
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.9.tgz",
|
||||||
"integrity": "sha512-j+7xYe+v+q2Id9qbBeCI8WX5NmZSRe8es1+0xntD/+gaWXznP8tFEkv5IgSaHf5dS1YwVMbX/4W6m937mj+wQw==",
|
"integrity": "sha512-M0MFoZzbUrRU4KNfCrDLnvyE7gub+peetoTid3TBIqtunaDJyXlwhakT+/VkvSXcfIzFfK/nkCs4nmyTmxdNSg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
|
@ -5760,8 +5760,8 @@
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"caniuse-lite": "^1.0.30001502",
|
"caniuse-lite": "^1.0.30001503",
|
||||||
"electron-to-chromium": "^1.4.428",
|
"electron-to-chromium": "^1.4.431",
|
||||||
"node-releases": "^2.0.12",
|
"node-releases": "^2.0.12",
|
||||||
"update-browserslist-db": "^1.0.11"
|
"update-browserslist-db": "^1.0.11"
|
||||||
},
|
},
|
||||||
|
@ -5943,9 +5943,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/caniuse-lite": {
|
"node_modules/caniuse-lite": {
|
||||||
"version": "1.0.30001503",
|
"version": "1.0.30001506",
|
||||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001503.tgz",
|
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001506.tgz",
|
||||||
"integrity": "sha512-Sf9NiF+wZxPfzv8Z3iS0rXM1Do+iOy2Lxvib38glFX+08TCYYYGR5fRJXk4d77C4AYwhUjgYgMsMudbh2TqCKw==",
|
"integrity": "sha512-6XNEcpygZMCKaufIcgpQNZNf00GEqc7VQON+9Rd0K1bMYo8xhMZRAo5zpbnbMNizi4YNgIDAFrdykWsvY3H4Hw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
|
@ -7498,9 +7498,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/dotenv": {
|
"node_modules/dotenv": {
|
||||||
"version": "16.1.4",
|
"version": "16.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.1.4.tgz",
|
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.3.1.tgz",
|
||||||
"integrity": "sha512-m55RtE8AsPeJBpOIFKihEmqUcoVncQIwo7x9U8ZwLEZw9ZpXboz2c+rvog+jUaJvVrZ5kBOeYQBX5+8Aa/OZQw==",
|
"integrity": "sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ==",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=12"
|
"node": ">=12"
|
||||||
},
|
},
|
||||||
|
@ -7648,9 +7648,9 @@
|
||||||
"integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="
|
"integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="
|
||||||
},
|
},
|
||||||
"node_modules/electron-to-chromium": {
|
"node_modules/electron-to-chromium": {
|
||||||
"version": "1.4.431",
|
"version": "1.4.436",
|
||||||
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.431.tgz",
|
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.436.tgz",
|
||||||
"integrity": "sha512-m232JTVmCawA2vG+1azVxhKZ9Sv1Q//xxNv5PkP5rWxGgQE8c3CiZFrh8Xnp+d1NmNxlu3QQrGIfdeW5TtXX5w==",
|
"integrity": "sha512-aktOxo8fnrMC8vOIBMVS3PXbT1nrPQ+SouUuN7Y0a+Rw3pOMrvIV92Ybnax7x4tugA+ZpYA5fOHTby7ama8OQQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/emittery": {
|
"node_modules/emittery": {
|
||||||
|
@ -7729,9 +7729,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/envinfo": {
|
"node_modules/envinfo": {
|
||||||
"version": "7.8.1",
|
"version": "7.9.0",
|
||||||
"resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.8.1.tgz",
|
"resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.9.0.tgz",
|
||||||
"integrity": "sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw==",
|
"integrity": "sha512-RODB4txU+xImYDemN5DqaKC0CHk05XSVkOX4pq0hK26Qx+1LChkuOyUDlGEjYb3ACr0n9qBhFjg37hQuJvpkRQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"peer": true,
|
"peer": true,
|
||||||
"bin": {
|
"bin": {
|
||||||
|
@ -7798,15 +7798,15 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/eslint": {
|
"node_modules/eslint": {
|
||||||
"version": "8.42.0",
|
"version": "8.43.0",
|
||||||
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.42.0.tgz",
|
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.43.0.tgz",
|
||||||
"integrity": "sha512-ulg9Ms6E1WPf67PHaEY4/6E2tEn5/f7FXGzr3t9cBMugOmf1INYvuUwwh1aXQN4MfJ6a5K2iNwP3w4AColvI9A==",
|
"integrity": "sha512-aaCpf2JqqKesMFGgmRPessmVKjcGXqdlAYLLC3THM8t5nBRZRQ+st5WM/hoJXkdioEXLLbXgclUpM0TXo5HX5Q==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@eslint-community/eslint-utils": "^4.2.0",
|
"@eslint-community/eslint-utils": "^4.2.0",
|
||||||
"@eslint-community/regexpp": "^4.4.0",
|
"@eslint-community/regexpp": "^4.4.0",
|
||||||
"@eslint/eslintrc": "^2.0.3",
|
"@eslint/eslintrc": "^2.0.3",
|
||||||
"@eslint/js": "8.42.0",
|
"@eslint/js": "8.43.0",
|
||||||
"@humanwhocodes/config-array": "^0.11.10",
|
"@humanwhocodes/config-array": "^0.11.10",
|
||||||
"@humanwhocodes/module-importer": "^1.0.1",
|
"@humanwhocodes/module-importer": "^1.0.1",
|
||||||
"@nodelib/fs.walk": "^1.2.8",
|
"@nodelib/fs.walk": "^1.2.8",
|
||||||
|
@ -12641,9 +12641,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/pirates": {
|
"node_modules/pirates": {
|
||||||
"version": "4.0.5",
|
"version": "4.0.6",
|
||||||
"resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.5.tgz",
|
"resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz",
|
||||||
"integrity": "sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==",
|
"integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 6"
|
"node": ">= 6"
|
||||||
|
@ -14206,9 +14206,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/semver": {
|
"node_modules/semver": {
|
||||||
"version": "7.5.1",
|
"version": "7.5.2",
|
||||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.5.1.tgz",
|
"resolved": "https://registry.npmjs.org/semver/-/semver-7.5.2.tgz",
|
||||||
"integrity": "sha512-Wvss5ivl8TMRZXXESstBA4uR5iXgEN/VC5/sOcuXdVLzcdkz4HWetIoRfG5gb5X+ij/G9rw9YoGn3QoQ8OCSpw==",
|
"integrity": "sha512-SoftuTROv/cRjCze/scjGyiDtcUyxw1rgYQSZY7XTmtR5hX+dm76iDbTH8TkLPHCQmlbQVSSbNZCPM2hb0knnQ==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"lru-cache": "^6.0.0"
|
"lru-cache": "^6.0.0"
|
||||||
},
|
},
|
||||||
|
@ -15477,9 +15477,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/terser": {
|
"node_modules/terser": {
|
||||||
"version": "5.18.0",
|
"version": "5.18.1",
|
||||||
"resolved": "https://registry.npmjs.org/terser/-/terser-5.18.0.tgz",
|
"resolved": "https://registry.npmjs.org/terser/-/terser-5.18.1.tgz",
|
||||||
"integrity": "sha512-pdL757Ig5a0I+owA42l6tIuEycRuM7FPY4n62h44mRLRfnOxJkkOHd6i89dOpwZlpF6JXBwaAHF6yWzFrt+QyA==",
|
"integrity": "sha512-j1n0Ao919h/Ai5r43VAnfV/7azUYW43GPxK7qSATzrsERfW7+y2QW9Cp9ufnRF5CQUWbnLSo7UJokSWCqg4tsQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@jridgewell/source-map": "^0.3.3",
|
"@jridgewell/source-map": "^0.3.3",
|
||||||
|
@ -16408,9 +16408,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/webpack": {
|
"node_modules/webpack": {
|
||||||
"version": "5.87.0",
|
"version": "5.88.0",
|
||||||
"resolved": "https://registry.npmjs.org/webpack/-/webpack-5.87.0.tgz",
|
"resolved": "https://registry.npmjs.org/webpack/-/webpack-5.88.0.tgz",
|
||||||
"integrity": "sha512-GOu1tNbQ7p1bDEoFRs2YPcfyGs8xq52yyPBZ3m2VGnXGtV9MxjrkABHm4V9Ia280OefsSLzvbVoXcfLxjKY/Iw==",
|
"integrity": "sha512-O3jDhG5e44qIBSi/P6KpcCcH7HD+nYIHVBhdWFxcLOcIGN8zGo5nqF3BjyNCxIh4p1vFdNnreZv2h2KkoAw3lw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"peer": true,
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
"start": "node server.js",
|
"start": "node server.js",
|
||||||
"lint": "eslint . --ext=.ts",
|
"lint": "eslint . --ext=.ts",
|
||||||
"format": "prettier --write .",
|
"format": "prettier --write .",
|
||||||
"format-check": "prettier --check ./**/*.ts",
|
"format-check": "prettier --check ./**/*.{ts,js}",
|
||||||
"test": "node ace test"
|
"test": "node ace test"
|
||||||
},
|
},
|
||||||
"eslintConfig": {
|
"eslintConfig": {
|
||||||
|
@ -74,7 +74,7 @@
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@adonisjs/auth": "^8.2.3",
|
"@adonisjs/auth": "^8.2.3",
|
||||||
"@adonisjs/core": "^5.8.3",
|
"@adonisjs/core": "^5.9.0",
|
||||||
"@adonisjs/lucid": "^18.3.0",
|
"@adonisjs/lucid": "^18.3.0",
|
||||||
"@adonisjs/repl": "^3.1.11",
|
"@adonisjs/repl": "^3.1.11",
|
||||||
"@adonisjs/session": "^6.4.0",
|
"@adonisjs/session": "^6.4.0",
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
module.exports = {
|
module.exports = {
|
||||||
plugins: {
|
plugins: {
|
||||||
tailwindcss: {},
|
tailwindcss: {},
|
||||||
autoprefixer: {},
|
autoprefixer: {},
|
||||||
},
|
},
|
||||||
}
|
};
|
||||||
|
|
|
@ -1,34 +1,43 @@
|
||||||
import { Ref } from 'vue';
|
import { Ref } from 'vue';
|
||||||
|
|
||||||
export interface Dataset {
|
export interface Dataset {
|
||||||
[key: string]: string | Ref<string>| boolean | Array<Title> | Array<Description>| Array<Person> | number | (IErrorMessage | undefined) | Coverage | Array<File>;
|
[key: string]:
|
||||||
language: Ref<string>;
|
| string
|
||||||
// licenses: Array<number>;
|
| Ref<string>
|
||||||
rights: boolean;
|
| boolean
|
||||||
type: string;
|
| Array<Title>
|
||||||
creating_corporation: string;
|
| Array<Description>
|
||||||
|
| Array<Person>
|
||||||
|
| number
|
||||||
|
| (IErrorMessage | undefined)
|
||||||
|
| Coverage
|
||||||
|
| Array<File>;
|
||||||
|
language: Ref<string>;
|
||||||
|
// licenses: Array<number>;
|
||||||
|
rights: boolean;
|
||||||
|
type: string;
|
||||||
|
creating_corporation: string;
|
||||||
titles: Array<Title>;
|
titles: Array<Title>;
|
||||||
descriptions: Array<Description>;
|
descriptions: Array<Description>;
|
||||||
authors: Array<Person>;
|
authors: Array<Person>;
|
||||||
contributors: Array<Person>;
|
contributors: Array<Person>;
|
||||||
project_id?: number;
|
project_id?: number;
|
||||||
embargo_date?: string,
|
embargo_date?: string;
|
||||||
coverage: Coverage,
|
coverage: Coverage;
|
||||||
errors?: IErrorMessage;
|
errors?: IErrorMessage;
|
||||||
// async (user): Promise<void>;
|
// async (user): Promise<void>;
|
||||||
subjects: Array<Subject>,
|
subjects: Array<Subject>;
|
||||||
files: Array<TestFile> | undefined,
|
files: Array<TestFile> | undefined;
|
||||||
// upload: TethysFile
|
// upload: TethysFile
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** Provides information about files and allows JavaScript in a web page to access their content. */
|
/** Provides information about files and allows JavaScript in a web page to access their content. */
|
||||||
export interface TestFile extends Blob {
|
export interface TestFile extends Blob {
|
||||||
readonly lastModified: number;
|
readonly lastModified: number;
|
||||||
readonly name: string;
|
readonly name: string;
|
||||||
readonly webkitRelativePath: string;
|
readonly webkitRelativePath: string;
|
||||||
label: string,
|
label: string;
|
||||||
sorting: number,
|
sorting: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
// export interface TethysFile {
|
// export interface TethysFile {
|
||||||
|
@ -39,7 +48,7 @@ export interface TestFile extends Blob {
|
||||||
|
|
||||||
export interface Subject {
|
export interface Subject {
|
||||||
// id: number;
|
// id: number;
|
||||||
language: string
|
language: string;
|
||||||
type: string;
|
type: string;
|
||||||
value: string;
|
value: string;
|
||||||
external_key?: string;
|
external_key?: string;
|
||||||
|
@ -68,7 +77,7 @@ export interface Person {
|
||||||
}
|
}
|
||||||
|
|
||||||
interface IErrorMessage {
|
interface IErrorMessage {
|
||||||
[key: string]: Array<string>;
|
[key: string]: Array<string>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Coverage {
|
export interface Coverage {
|
||||||
|
@ -84,7 +93,7 @@ export interface Coverage {
|
||||||
depth_max?: number;
|
depth_max?: number;
|
||||||
depth_absolut?: number;
|
depth_absolut?: number;
|
||||||
|
|
||||||
time_min?: number,
|
time_min?: number;
|
||||||
time_max?: number,
|
time_max?: number;
|
||||||
time_absolut?: number
|
time_absolut?: number;
|
||||||
}
|
}
|
|
@ -1,25 +1,25 @@
|
||||||
export const basic = {
|
export const basic = {
|
||||||
aside: "bg-gray-800",
|
aside: 'bg-gray-800',
|
||||||
asideScrollbars: "aside-scrollbars-gray",
|
asideScrollbars: 'aside-scrollbars-gray',
|
||||||
asideBrand: "bg-gray-900 text-white",
|
asideBrand: 'bg-gray-900 text-white',
|
||||||
asideMenuItem: "text-gray-300 hover:text-white",
|
asideMenuItem: 'text-gray-300 hover:text-white',
|
||||||
asideMenuItemActive: "font-bold text-white",
|
asideMenuItemActive: 'font-bold text-white',
|
||||||
asideMenuDropdown: "bg-gray-700/50",
|
asideMenuDropdown: 'bg-gray-700/50',
|
||||||
navBarItemLabel: "text-black",
|
navBarItemLabel: 'text-black',
|
||||||
navBarItemLabelHover: "hover:text-blue-500",
|
navBarItemLabelHover: 'hover:text-blue-500',
|
||||||
navBarItemLabelActiveColor: "text-blue-600",
|
navBarItemLabelActiveColor: 'text-blue-600',
|
||||||
overlay: "from-gray-700 via-gray-900 to-gray-700",
|
overlay: 'from-gray-700 via-gray-900 to-gray-700',
|
||||||
};
|
};
|
||||||
|
|
||||||
export const white = {
|
export const white = {
|
||||||
aside: "bg-white",
|
aside: 'bg-white',
|
||||||
asideScrollbars: "aside-scrollbars-light",
|
asideScrollbars: 'aside-scrollbars-light',
|
||||||
asideBrand: "",
|
asideBrand: '',
|
||||||
asideMenuItem: "text-blue-600 hover:text-black dark:text-white",
|
asideMenuItem: 'text-blue-600 hover:text-black dark:text-white',
|
||||||
asideMenuItemActive: "font-bold text-black dark:text-white",
|
asideMenuItemActive: 'font-bold text-black dark:text-white',
|
||||||
asideMenuDropdown: "bg-gray-100/75",
|
asideMenuDropdown: 'bg-gray-100/75',
|
||||||
navBarItemLabel: "text-blue-600",
|
navBarItemLabel: 'text-blue-600',
|
||||||
navBarItemLabelHover: "hover:text-black",
|
navBarItemLabelHover: 'hover:text-black',
|
||||||
navBarItemLabelActiveColor: "text-black",
|
navBarItemLabelActiveColor: 'text-black',
|
||||||
overlay: "from-white via-gray-100 to-white",
|
overlay: 'from-white via-gray-100 to-white',
|
||||||
};
|
};
|
||||||
|
|
|
@ -2,18 +2,18 @@ import Route from '@ioc:Adonis/Core/Route';
|
||||||
|
|
||||||
// API
|
// API
|
||||||
Route.group(() => {
|
Route.group(() => {
|
||||||
// Route.post("register", "AuthController.register");
|
// Route.post("register", "AuthController.register");
|
||||||
// Route.post("login", "AuthController.login");
|
// Route.post("login", "AuthController.login");
|
||||||
|
|
||||||
Route.group(() => {
|
Route.group(() => {
|
||||||
Route.get('authors', 'AuthorsController.index').as('author.index');
|
Route.get('authors', 'AuthorsController.index').as('author.index');
|
||||||
Route.get('datasets', 'DatasetController.index').as('dataset.index');
|
Route.get('datasets', 'DatasetController.index').as('dataset.index');
|
||||||
Route.get('persons', 'AuthorsController.persons').as('author.persons');
|
Route.get('persons', 'AuthorsController.persons').as('author.persons');
|
||||||
// Route.get("author/:id", "TodosController.show");
|
// Route.get("author/:id", "TodosController.show");
|
||||||
// Route.put("author/update", "TodosController.update");
|
// Route.put("author/update", "TodosController.update");
|
||||||
// Route.post("author", "TodosController.store");
|
// Route.post("author", "TodosController.store");
|
||||||
});
|
});
|
||||||
// .middleware("auth:api");
|
// .middleware("auth:api");
|
||||||
})
|
})
|
||||||
.namespace('App/Controllers/Http/Api')
|
.namespace('App/Controllers/Http/Api')
|
||||||
.prefix('api');
|
.prefix('api');
|
||||||
|
|
|
@ -11,6 +11,34 @@ https://issuehunt.io/r/adonisjs/validator/issues/84
|
||||||
// import { string } from '@ioc:Adonis/Core/Helpers';
|
// import { string } from '@ioc:Adonis/Core/Helpers';
|
||||||
import { validator } from '@ioc:Adonis/Core/Validator';
|
import { validator } from '@ioc:Adonis/Core/Validator';
|
||||||
|
|
||||||
|
validator.rule('uniqueArray', (dataArray, [field], { pointer, arrayExpressionPointer, errorReporter }) => {
|
||||||
|
const array = dataArray; //validator.helpers.getFieldValue(data, field, tip);
|
||||||
|
|
||||||
|
if (!Array.isArray(array)) {
|
||||||
|
throw new Error(`The ${pointer} must be an array.`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const uniqueValues = new Set();
|
||||||
|
for (let i = 0; i < array.length; i++) {
|
||||||
|
const item = array[i];
|
||||||
|
const attributeValue = item[field]; // Extract the attribute value for uniqueness check
|
||||||
|
|
||||||
|
if (uniqueValues.has(attributeValue)) {
|
||||||
|
// throw new Error(`The ${field} array contains duplicate values for the ${field} attribute.`)
|
||||||
|
errorReporter.report(
|
||||||
|
pointer,
|
||||||
|
'uniqueArray', // Keep an eye on this
|
||||||
|
`The ${pointer} array contains duplicate values for the ${field} attribute.`,
|
||||||
|
arrayExpressionPointer,
|
||||||
|
{ field, array: pointer },
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
uniqueValues.add(attributeValue);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
validator.rule(
|
validator.rule(
|
||||||
'translatedLanguage',
|
'translatedLanguage',
|
||||||
(value, [mainLanguageField, typeField], { root, tip, pointer, arrayExpressionPointer, errorReporter }) => {
|
(value, [mainLanguageField, typeField], { root, tip, pointer, arrayExpressionPointer, errorReporter }) => {
|
||||||
|
|
|
@ -15,10 +15,10 @@ module.exports = {
|
||||||
'primary': '#22C55E',
|
'primary': '#22C55E',
|
||||||
'primary-dark': '#DCFCE7',
|
'primary-dark': '#DCFCE7',
|
||||||
},
|
},
|
||||||
// fontFamily: {
|
fontFamily: {
|
||||||
// sans: ['Inter', ...defaultTheme.fontFamily.sans],
|
sans: ['Inter', ...defaultTheme.fontFamily.sans],
|
||||||
// logo: ['Archivo Black', ...defaultTheme.fontFamily.sans],
|
logo: ['Archivo Black', ...defaultTheme.fontFamily.sans],
|
||||||
// },
|
},
|
||||||
zIndex: {
|
zIndex: {
|
||||||
'-1': '-1',
|
'-1': '-1',
|
||||||
},
|
},
|
||||||
|
@ -61,9 +61,7 @@ module.exports = {
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'scrollbarWidth': 'thin',
|
'scrollbarWidth': 'thin',
|
||||||
'scrollbarColor': `${theme(`colors.${color}.${thumb}`)} ${theme(
|
'scrollbarColor': `${theme(`colors.${color}.${thumb}`)} ${theme(`colors.${color}.${track}`)}`,
|
||||||
`colors.${color}.${track}`,
|
|
||||||
)}`,
|
|
||||||
'&::-webkit-scrollbar': {
|
'&::-webkit-scrollbar': {
|
||||||
width: '8px',
|
width: '8px',
|
||||||
height: '8px',
|
height: '8px',
|
||||||
|
|
|
@ -3,39 +3,39 @@ const Encore = require('@symfony/webpack-encore');
|
||||||
const { VueLoaderPlugin } = require('vue-loader');
|
const { VueLoaderPlugin } = require('vue-loader');
|
||||||
|
|
||||||
const babelLoader = {
|
const babelLoader = {
|
||||||
// test: /\.js$/,
|
// test: /\.js$/,
|
||||||
test: /\.(js|jsx|ts|tsx)$/,
|
test: /\.(js|jsx|ts|tsx)$/,
|
||||||
// exclude: /(node_modules|bower_components)/,
|
// exclude: /(node_modules|bower_components)/,
|
||||||
// exclude: file => (
|
// exclude: file => (
|
||||||
// /node_modules/.test(file) &&
|
// /node_modules/.test(file) &&
|
||||||
// !/\.vue\.js/.test(file)
|
// !/\.vue\.js/.test(file)
|
||||||
// ),
|
// ),
|
||||||
exclude: /node_modules/,
|
exclude: /node_modules/,
|
||||||
use: {
|
use: {
|
||||||
loader: 'babel-loader',
|
loader: 'babel-loader',
|
||||||
options: {
|
options: {
|
||||||
presets: [
|
presets: [
|
||||||
// ['@babel/preset-env', {
|
// ['@babel/preset-env', {
|
||||||
// "targets": "> 0.25%, not dead"
|
// "targets": "> 0.25%, not dead"
|
||||||
// // "targets": {
|
// // "targets": {
|
||||||
// // "edge": "17",
|
// // "edge": "17",
|
||||||
// // "firefox": "60",
|
// // "firefox": "60",
|
||||||
// // "chrome": "67",
|
// // "chrome": "67",
|
||||||
// // "safari": "11.1"
|
// // "safari": "11.1"
|
||||||
// // }
|
// // }
|
||||||
// }],
|
// }],
|
||||||
['@babel/preset-env', {}],
|
['@babel/preset-env', {}],
|
||||||
'babel-preset-typescript-vue3', //because of new vue setup method
|
'babel-preset-typescript-vue3', //because of new vue setup method
|
||||||
// "@babel/preset-typescript"
|
// "@babel/preset-typescript"
|
||||||
],
|
],
|
||||||
plugins: [
|
plugins: [
|
||||||
// "@babel/plugin-transform-runtime",
|
// "@babel/plugin-transform-runtime",
|
||||||
['@babel/plugin-proposal-decorators', { legacy: true }],
|
['@babel/plugin-proposal-decorators', { legacy: true }],
|
||||||
|
|
||||||
'@babel/proposal-class-properties',
|
'@babel/proposal-class-properties',
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
// const Components = require('unplugin-vue-components/webpack')
|
// const Components = require('unplugin-vue-components/webpack')
|
||||||
|
@ -47,7 +47,7 @@ const babelLoader = {
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
if (!Encore.isRuntimeEnvironmentConfigured()) {
|
if (!Encore.isRuntimeEnvironmentConfigured()) {
|
||||||
Encore.configureRuntimeEnvironment(process.env.NODE_ENV || 'dev');
|
Encore.configureRuntimeEnvironment(process.env.NODE_ENV || 'dev');
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -168,23 +168,23 @@ Encore.enableVersioning(Encore.isProduction());
|
||||||
|
|
|
|
||||||
*/
|
*/
|
||||||
Encore.configureDevServerOptions((options) => {
|
Encore.configureDevServerOptions((options) => {
|
||||||
/**
|
/**
|
||||||
* Normalize "options.static" property to an array
|
* Normalize "options.static" property to an array
|
||||||
*/
|
*/
|
||||||
if (!options.static) {
|
if (!options.static) {
|
||||||
options.static = [];
|
options.static = [];
|
||||||
} else if (!Array.isArray(options.static)) {
|
} else if (!Array.isArray(options.static)) {
|
||||||
options.static = [options.static];
|
options.static = [options.static];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enable live reload and add views directory
|
* Enable live reload and add views directory
|
||||||
*/
|
*/
|
||||||
options.liveReload = true;
|
options.liveReload = true;
|
||||||
options.static.push({
|
options.static.push({
|
||||||
directory: join(__dirname, './resources/views'),
|
directory: join(__dirname, './resources/views'),
|
||||||
watch: true,
|
watch: true,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -268,42 +268,41 @@ Encore.enablePostCssLoader();
|
||||||
// // }
|
// // }
|
||||||
// })
|
// })
|
||||||
Encore.addLoader({
|
Encore.addLoader({
|
||||||
test: /\.vue$/,
|
test: /\.vue$/,
|
||||||
loader: 'vue-loader',
|
loader: 'vue-loader',
|
||||||
options: {
|
options: {
|
||||||
// loaders: {
|
// loaders: {
|
||||||
// ts: 'ts-loader',
|
// ts: 'ts-loader',
|
||||||
// },
|
// },
|
||||||
cacheDirectory: 'C:\\Users\\kaiarn\\Documents\\Software\\tethys.viewer\\node_modules\\.cache\\vue-loader',
|
cacheDirectory: 'C:\\Users\\kaiarn\\Documents\\Software\\tethys.viewer\\node_modules\\.cache\\vue-loader',
|
||||||
cacheIdentifier: 'f930df3e',
|
cacheIdentifier: 'f930df3e',
|
||||||
babelParserPlugins: ['jsx', 'classProperties', 'decorators-legacy'],
|
babelParserPlugins: ['jsx', 'classProperties', 'decorators-legacy'],
|
||||||
},
|
},
|
||||||
})
|
}).addPlugin(new VueLoaderPlugin());
|
||||||
.addPlugin(new VueLoaderPlugin())
|
// .addAliases({
|
||||||
// .addAliases({
|
// vue$: 'vue/dist/vue.runtime.esm-bundler.js',
|
||||||
// vue$: 'vue/dist/vue.runtime.esm-bundler.js',
|
// });
|
||||||
// });
|
|
||||||
|
|
||||||
Encore.addLoader(babelLoader)
|
Encore.addLoader(babelLoader)
|
||||||
// Encore.enableTypeScriptLoader(config => {
|
// Encore.enableTypeScriptLoader(config => {
|
||||||
// // Loader-specific options
|
// // Loader-specific options
|
||||||
// config.configFile = 'tsconfig.vue.json';
|
// config.configFile = 'tsconfig.vue.json';
|
||||||
// config.appendTsSuffixTo = [/\.vue$/];
|
// config.appendTsSuffixTo = [/\.vue$/];
|
||||||
// config.transpileOnly = true;
|
// config.transpileOnly = true;
|
||||||
// config.happyPackMode = false;
|
// config.happyPackMode = false;
|
||||||
// }, {
|
// }, {
|
||||||
// // Directly change the exclude rule
|
// // Directly change the exclude rule
|
||||||
// exclude: /node_modules/,
|
// exclude: /node_modules/,
|
||||||
|
|
||||||
// })
|
// })
|
||||||
.addAliases({
|
.addAliases({
|
||||||
'@': join(__dirname, 'resources/js'),
|
'@': join(__dirname, 'resources/js'),
|
||||||
vue$: 'vue/dist/vue.runtime.esm-bundler.js'
|
'vue$': 'vue/dist/vue.runtime.esm-bundler.js',
|
||||||
})
|
})
|
||||||
.configureDefinePlugin((options) => {
|
.configureDefinePlugin((options) => {
|
||||||
options['__VUE_OPTIONS_API__'] = true;
|
options['__VUE_OPTIONS_API__'] = true;
|
||||||
options['__VUE_PROD_DEVTOOLS__'] = false;
|
options['__VUE_PROD_DEVTOOLS__'] = false;
|
||||||
});
|
});
|
||||||
|
|
||||||
// Encore.addAliases({
|
// Encore.addAliases({
|
||||||
// '@': resolve(__dirname, 'resources/js')
|
// '@': resolve(__dirname, 'resources/js')
|
||||||
|
@ -364,7 +363,7 @@ Encore.addLoader(babelLoader)
|
||||||
*/
|
*/
|
||||||
const config = Encore.getWebpackConfig();
|
const config = Encore.getWebpackConfig();
|
||||||
config.infrastructureLogging = {
|
config.infrastructureLogging = {
|
||||||
level: 'warn',
|
level: 'warn',
|
||||||
};
|
};
|
||||||
config.stats = 'errors-warnings';
|
config.stats = 'errors-warnings';
|
||||||
// config.resolve.extensions.push('.vue');
|
// config.resolve.extensions.push('.vue');
|
||||||
|
@ -381,7 +380,7 @@ config.stats = 'errors-warnings';
|
||||||
// // // '@': path.resolve(__dirname, 'resources/js'),
|
// // // '@': path.resolve(__dirname, 'resources/js'),
|
||||||
// // }
|
// // }
|
||||||
// };
|
// };
|
||||||
config.resolve.extensions = [ '.tsx', '.ts', '.mjs', '.js', '.jsx', '.vue', '.json', '.wasm'];
|
config.resolve.extensions = ['.tsx', '.ts', '.mjs', '.js', '.jsx', '.vue', '.json', '.wasm'];
|
||||||
|
|
||||||
// config.resolve = {
|
// config.resolve = {
|
||||||
// // vue: 'vue/dist/vue.js'
|
// // vue: 'vue/dist/vue.js'
|
||||||
|
@ -390,8 +389,6 @@ config.resolve.extensions = [ '.tsx', '.ts', '.mjs', '.js', '.jsx', '.vue', '.js
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
| Export config
|
| Export config
|
||||||
|
|
Loading…
Reference in New Issue
Block a user