tethys.backend/app/Controllers/Http/Admin/UsersController.ts
Arno Kaimbacher ae0c471e93 - now authenticated user can change password with check of old password and password confirmination
- cchanged route app.dashboard to apps.dashboard
- add editor and reviewer relation to Dataset.ts
- added personal menu in asideMenu
- added Approve.vue for editor
- show warning in Index.vue  (editor), if no dataset is loaded
- user Receive.vue without inertia helper form
- npm updates
- added routes in routes.ts
2023-12-12 15:22:25 +01:00

257 lines
9.7 KiB
TypeScript

import type { HttpContextContract } from '@ioc:Adonis/Core/HttpContext';
import User from 'App/Models/User';
import Role from 'App/Models/Role';
import type { ModelQueryBuilderContract } from '@ioc:Adonis/Lucid/Orm';
import CreateUserValidator from 'App/Validators/CreateUserValidator';
import UpdateUserValidator from 'App/Validators/UpdateUserValidator';
import { RenderResponse } from '@ioc:EidelLev/Inertia';
// import { schema, rules } from '@ioc:Adonis/Core/Validator';
import Hash from '@ioc:Adonis/Core/Hash';
import { schema, rules } from '@ioc:Adonis/Core/Validator';
export default class UsersController {
public async index({ auth, request, inertia }: HttpContextContract) {
const page = request.input('page', 1);
// const limit = 10
let users: ModelQueryBuilderContract<typeof User, User> = User.query();
if (request.input('search')) {
// users = users.whereRaw('name like %?%', [request.input('search')])
const searchTerm = request.input('search');
users.where('login', 'ilike', `%${searchTerm}%`);
}
if (request.input('sort')) {
type SortOrder = 'asc' | 'desc' | undefined;
let attribute = request.input('sort');
let sortOrder: SortOrder = 'asc';
// if (strncmp($attribute, '-', 1) === 0) {
if (attribute.substr(0, 1) === '-') {
sortOrder = 'desc';
// attribute = substr(attribute, 1);
attribute = attribute.substr(1);
}
// $users->orderBy($attribute, $sort_order);
users.orderBy(attribute, sortOrder);
} else {
// users.orderBy('created_at', 'desc');
users.orderBy('id', 'asc');
}
// const users = await User.query().orderBy('login').paginate(page, limit);
let usersResult = await users // User.query()
// .orderBy('login')
// .filter(qs)
// .preload('focusInterests')
// .preload('role')
.paginate(page, 5);
// var test = request.all();
return inertia.render('Admin/User/Index', {
// testing: 'this is a test',
users: usersResult.toJSON(),
filters: request.all(),
can: {
create: await auth.user?.can(['user-create']),
edit: await auth.user?.can(['user-edit']),
delete: await auth.user?.can(['user-delete']),
},
});
}
public async create({ inertia }: HttpContextContract) {
// let rolesPluck = {};
// (await Role.query().select('id', 'name')).forEach((user) => {
// rolesPluck[user.id] = user.name;
// });
const roles = await Role.query().select('id', 'name').pluck('name', 'id');
return inertia.render('Admin/User/Create', {
roles: roles,
});
}
public async store({ request, response, session }: HttpContextContract) {
// node ace make:validator CreateUser
try {
// Step 2 - Validate request body against the schema
await request.validate(CreateUserValidator);
// console.log({ payload });
} catch (error) {
// Step 3 - Handle errors
// return response.badRequest(error.messages);
throw error;
}
const input = request.only(['login', 'email', 'password']);
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', 'User has been created successfully');
return response.redirect().toRoute('user.index');
}
public async show({ request, inertia }: HttpContextContract) {
const id = request.param('id');
const user = await User.query().where('id', id).firstOrFail();
const roles = await Role.query().pluck('name', 'id');
// const userHasRoles = user.roles;
const userRoles = await user.related('roles').query().orderBy('name').pluck('id');
return inertia.render('Admin/User/Show', {
roles: roles,
user: user,
userHasRoles: userRoles,
});
}
public async edit({ request, inertia }: HttpContextContract) {
const id = request.param('id');
const user = await User.query().where('id', id).firstOrFail();
const roles = await Role.query().pluck('name', 'id');
// const userHasRoles = user.roles;
const userHasRoles = await user.related('roles').query().orderBy('name').pluck('id');
// let test = Object.keys(userHasRoles).map((key) => userHasRoles[key]);
return inertia.render('Admin/User/Edit', {
roles: roles,
user: user,
userHasRoles: Object.keys(userHasRoles).map((key) => userHasRoles[key]), //convert object to array with role ids
});
}
public async update({ request, response, session }: HttpContextContract) {
// node ace make:validator UpdateUser
const id = request.param('id');
const user = await User.query().where('id', id).firstOrFail();
// validate update form
await request.validate(UpdateUserValidator);
// password is optional
let input;
if (request.input('password')) {
input = request.only(['login', 'email', 'password']);
} else {
input = request.only(['login', 'email']);
}
await user.merge(input).save();
// await user.save();
if (request.input('roles')) {
const roles: Array<number> = request.input('roles');
await user.related('roles').sync(roles);
}
session.flash('message', 'User has been updated successfully');
return response.redirect().toRoute('user.index');
}
public async destroy({ request, response, session }: HttpContextContract) {
const id = request.param('id');
const user = await User.findOrFail(id);
await user.delete();
session.flash('message', `User ${user.login} has been deleted.`);
return response.redirect().toRoute('user.index');
}
/**
* Show the user a form to change their personal information & password.
*
* @return — \Inertia\Response
*/
public accountInfo({ inertia, auth }: HttpContextContract): RenderResponse {
const user = auth.user;
// const id = request.param('id');
// const user = await User.query().where('id', id).firstOrFail();
return inertia.render('Admin/User/AccountInfo', {
user: user,
});
}
/**
* Save the modified personal information for a user.
*
* @param HttpContextContract ctx
* @return : RedirectContract
*/
public async accountInfoStoreOld({ request, response, auth, session }: HttpContextContract) {
// validate update form
await request.validate(UpdateUserValidator);
const payload = request.only(['login', 'email']);
auth.user?.merge(payload);
const user = await auth.user?.save();
// $user = \Auth::user()->update($request->except(['_token']));
let message;
if (user) {
message = 'Account updated successfully.';
} else {
message = 'Error while saving. Please try again.';
}
session.flash(message);
return response.redirect().toRoute('admin.account.info');
//->with('message', __($message));
}
public async accountInfoStore({ auth, request, response, session }) {
const passwordSchema = schema.create({
old_password: schema.string({ trim: true }, [rules.required()]),
new_password: schema.string({ trim: true }, [rules.minLength(8), rules.maxLength(255), rules.confirmed('confirm_password')]),
confirm_password: schema.string({ trim: true }, [rules.required()]),
});
try {
await request.validate({ schema: passwordSchema });
} catch (error) {
// return response.badRequest(error.messages);
throw error;
}
try {
const user = await auth.user;
const { old_password, new_password } = request.only(['old_password', 'new_password']);
// if (!(old_password && new_password && confirm_password)) {
// return response.status(400).send({ message: 'Old password and new password are required.' });
// }
// Verify if the provided old password matches the user's current password
const isSame = await Hash.verify(user.password, old_password);
if (!isSame) {
return response.flash({ message: 'Old password is incorrect.' }).redirect().back();
}
// Hash the new password before updating the user's password
user.password = new_password;
await user.save();
// return response.status(200).send({ message: 'Password updated successfully.' });
session.flash('Password updated successfully.');
return response.redirect().toRoute('settings.user');
} catch (error) {
// return response.status(500).send({ message: 'Internal server error.' });
return response.flash('warning', `Invalid server state. Internal server error.`).redirect().back();
}
}
// 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
// }
}