- improved vies and controllers for rejecting datasets with email for reviewer and editor role
Some checks failed
CI Pipeline / japa-tests (push) Failing after 1m8s
Some checks failed
CI Pipeline / japa-tests (push) Failing after 1m8s
- falsh also error via config/inertia.ts - npm updates
This commit is contained in:
parent
b06ccae603
commit
2235f3905a
12 changed files with 627 additions and 370 deletions
|
@ -21,7 +21,7 @@ export default class LicenseController {
|
|||
await license.save();
|
||||
|
||||
// session.flash({ message: 'person has been deactivated!' });
|
||||
return response.flash('person has been deactivated!', 'message').toRoute('settings.license.index')
|
||||
return response.flash('License has been deactivated!', 'message').toRoute('settings.license.index')
|
||||
}
|
||||
|
||||
public async up({ request, response }: HttpContext) {
|
||||
|
@ -31,7 +31,7 @@ export default class LicenseController {
|
|||
await license.save();
|
||||
|
||||
// session.flash({ message: 'person has been activated!' });
|
||||
return response.flash('person has been activated!', 'message').toRoute('settings.license.index');
|
||||
return response.flash('License has been activated!', 'message').toRoute('settings.license.index');
|
||||
}
|
||||
|
||||
// public async edit({ request, inertia }: HttpContext) {
|
||||
|
|
|
@ -15,9 +15,12 @@ import { DoiClient } from '#app/Library/Doi/DoiClient';
|
|||
import DoiClientException from '#app/exceptions/DoiClientException';
|
||||
import logger from '@adonisjs/core/services/logger';
|
||||
import { HttpException } from 'node-exceptions';
|
||||
import { ModelQueryBuilderContract } from "@adonisjs/lucid/types/model";
|
||||
import { ModelQueryBuilderContract } from '@adonisjs/lucid/types/model';
|
||||
import vine, { SimpleMessagesProvider } from '@vinejs/vine';
|
||||
|
||||
import mail from '@adonisjs/mail/services/main';
|
||||
// import { resolveMx } from 'dns/promises';
|
||||
// import * as net from 'net';
|
||||
import { validate } from 'deep-email-validator';
|
||||
// Create a new instance of the client
|
||||
const client = new Client({ node: 'http://localhost:9200' }); // replace with your OpenSearch endpoint
|
||||
|
||||
|
@ -146,7 +149,7 @@ export default class DatasetsController {
|
|||
try {
|
||||
await dataset.related('editor').associate(user); // speichert schon ab
|
||||
// await dataset.save();
|
||||
return response.toRoute('editor.dataset.list').flash('message', `You have accepted dataset ${dataset.id}!`);
|
||||
return response.toRoute('editor.dataset.list').flash(`You have accepted dataset ${dataset.id}!`, 'message');
|
||||
} catch (error) {
|
||||
// Handle any errors
|
||||
console.error(error);
|
||||
|
@ -231,7 +234,7 @@ export default class DatasetsController {
|
|||
// .preload('titles')
|
||||
// .preload('descriptions')
|
||||
.preload('user', (builder) => {
|
||||
builder.select('id', 'login');
|
||||
builder.select('id', 'login', 'email');
|
||||
})
|
||||
.firstOrFail();
|
||||
|
||||
|
@ -252,22 +255,86 @@ export default class DatasetsController {
|
|||
});
|
||||
}
|
||||
|
||||
public async rejectUpdate({ request, response }: HttpContext) {
|
||||
// private async checkEmailDomain(email: string): Promise<boolean> {
|
||||
// const domain = email.split('@')[1];
|
||||
|
||||
// try {
|
||||
// // Step 1: Check MX records for the domain
|
||||
// const mxRecords = await resolveMx(domain);
|
||||
// if (mxRecords.length === 0) {
|
||||
// return false; // No MX records, can't send email
|
||||
// }
|
||||
|
||||
// // Sort MX records by priority
|
||||
// mxRecords.sort((a, b) => a.priority - b.priority);
|
||||
|
||||
// // Step 2: Attempt SMTP connection to the first available mail server
|
||||
// const smtpServer = mxRecords[0].exchange;
|
||||
|
||||
// return await this.checkMailboxExists(smtpServer, email);
|
||||
// } catch (error) {
|
||||
// console.error('Error during MX lookup or SMTP validation:', error);
|
||||
// return false;
|
||||
// }
|
||||
// }
|
||||
|
||||
//// Helper function to check if the mailbox exists using SMTP
|
||||
// private async checkMailboxExists(smtpServer: string, email: string): Promise<boolean> {
|
||||
// return new Promise((resolve, reject) => {
|
||||
// const socket = net.createConnection(25, smtpServer);
|
||||
|
||||
// socket.on('connect', () => {
|
||||
// socket.write(`HELO ${smtpServer}\r\n`);
|
||||
// socket.write(`MAIL FROM: <test@example.com>\r\n`);
|
||||
// socket.write(`RCPT TO: <${email}>\r\n`);
|
||||
// });
|
||||
|
||||
// socket.on('data', (data) => {
|
||||
// const response = data.toString();
|
||||
// if (response.includes('250')) {
|
||||
// // 250 is an SMTP success code
|
||||
// socket.end();
|
||||
// resolve(true); // Email exists
|
||||
// } else if (response.includes('550')) {
|
||||
// // 550 means the mailbox doesn't exist
|
||||
// socket.end();
|
||||
// resolve(false); // Email doesn't exist
|
||||
// }
|
||||
// });
|
||||
|
||||
// socket.on('error', (error) => {
|
||||
// console.error('SMTP connection error:', error);
|
||||
// socket.end();
|
||||
// resolve(false);
|
||||
// });
|
||||
|
||||
// socket.on('end', () => {
|
||||
// // SMTP connection closed
|
||||
// });
|
||||
|
||||
// socket.setTimeout(5000, () => {
|
||||
// // Timeout after 5 seconds
|
||||
// socket.end();
|
||||
// resolve(false); // Assume email doesn't exist if no response
|
||||
// });
|
||||
// });
|
||||
// }
|
||||
|
||||
public async rejectUpdate({ request, response, auth }: HttpContext) {
|
||||
const authUser = auth.user!;
|
||||
|
||||
const id = request.param('id');
|
||||
const dataset = await Dataset.query()
|
||||
.where('id', id)
|
||||
.preload('user', (builder) => {
|
||||
builder.select('id', 'login');
|
||||
builder.select('id', 'login', 'email');
|
||||
})
|
||||
.firstOrFail();
|
||||
|
||||
// const newSchema = schema.create({
|
||||
// server_state: schema.string({ trim: true }),
|
||||
// reject_reviewer_note: schema.string({ trim: true }, [rules.minLength(10), rules.maxLength(500)]),
|
||||
// });
|
||||
const newSchema = vine.object({
|
||||
server_state: vine.string().trim(),
|
||||
reject_editor_note: vine.string().trim().minLength(10).maxLength(500),
|
||||
send_mail: vine.boolean().optional(),
|
||||
});
|
||||
|
||||
try {
|
||||
|
@ -285,29 +352,56 @@ export default class DatasetsController {
|
|||
// return response.flash('warning', 'Invalid server state. Dataset cannot be released to editor').redirect().back();
|
||||
return response
|
||||
.flash(
|
||||
'warning',
|
||||
`Invalid server state. Dataset with id ${id} cannot be rejected. Datset has server state ${dataset.server_state}.`,
|
||||
'warning'
|
||||
)
|
||||
.redirect()
|
||||
.toRoute('reviewer.dataset.list');
|
||||
.toRoute('editor.dataset.list');
|
||||
}
|
||||
|
||||
// dataset.server_state = 'reviewed';
|
||||
dataset.server_state = 'rejected_editor';
|
||||
const rejectEditorNote = request.input('reject_editor_note', '');
|
||||
dataset.reject_editor_note = rejectEditorNote;
|
||||
|
||||
try {
|
||||
// await dataset.related('editor').associate(user); // speichert schon ab
|
||||
await dataset.save();
|
||||
return response
|
||||
.toRoute('editor.dataset.list')
|
||||
.flash('message', `You have rejected dataset ${dataset.id}! to submitter ${dataset.user.login}`);
|
||||
} catch (error) {
|
||||
// Handle any errors
|
||||
console.error(error);
|
||||
return response.status(500).json({ error: 'An error occurred while reviewing the data.' });
|
||||
// add logic for sending reject message
|
||||
const sendMail = request.input('send_email', false);
|
||||
// const validRecipientEmail = await this.checkEmailDomain('arno.kaimbacher@outlook.at');
|
||||
const validationResult = await validate({
|
||||
email: dataset.user.email,
|
||||
validateSMTP: false,
|
||||
});
|
||||
const validRecipientEmail: boolean = validationResult.valid;
|
||||
|
||||
let emailStatusMessage = '';
|
||||
|
||||
if (sendMail == true) {
|
||||
if (dataset.user.email && validRecipientEmail) {
|
||||
try {
|
||||
await mail.send((message) => {
|
||||
message.to(dataset.user.email).subject('Dataset Rejection Notification').html(`
|
||||
<p>Dear ${dataset.user.login},</p>
|
||||
<p>Your dataset with ID ${dataset.id} has been rejected.</p>
|
||||
<p>Reason for rejection: ${rejectEditorNote}</p>
|
||||
<p>Best regards,<br>Your Tethys editor: ${authUser.login}</p>
|
||||
`);
|
||||
});
|
||||
emailStatusMessage = ` A rejection email was successfully sent to ${dataset.user.email}.`;
|
||||
} catch (error) {
|
||||
logger.error(error);
|
||||
return response.flash('Dataset has not been rejected due to an email error: ' + error.message, 'error').toRoute('editor.dataset.list');
|
||||
}
|
||||
} else {
|
||||
emailStatusMessage = ` However, the email could not be sent because the submitter's email address (${dataset.user.email}) is not valid.`;
|
||||
}
|
||||
}
|
||||
|
||||
await dataset.save();
|
||||
return response
|
||||
.flash(
|
||||
`You have successfully rejected dataset ${dataset.id} submitted by ${dataset.user.login}.${emailStatusMessage}`,
|
||||
'message',
|
||||
)
|
||||
.toRoute('editor.dataset.list');
|
||||
}
|
||||
|
||||
public async publish({ request, inertia, response }: HttpContext) {
|
||||
|
@ -401,10 +495,9 @@ export default class DatasetsController {
|
|||
|
||||
let prefix = '';
|
||||
let base_domain = '';
|
||||
// const datacite_environment = process.env.DATACITE_ENVIRONMENT || 'debug';
|
||||
// const datacite_environment = process.env.DATACITE_ENVIRONMENT || 'debug';
|
||||
prefix = process.env.DATACITE_PREFIX || '';
|
||||
base_domain = process.env.BASE_DOMAIN || '';
|
||||
|
||||
|
||||
// register DOI:
|
||||
const doiValue = prefix + '/tethys.' + dataset.publish_id; //'10.21388/tethys.213'
|
||||
|
|
|
@ -4,14 +4,16 @@ import Dataset from '#models/dataset';
|
|||
import Field from '#app/Library/Field';
|
||||
import BaseModel from '#models/base_model';
|
||||
import { DateTime } from 'luxon';
|
||||
import { ModelQueryBuilderContract } from "@adonisjs/lucid/types/model";
|
||||
import { ModelQueryBuilderContract } from '@adonisjs/lucid/types/model';
|
||||
import vine from '@vinejs/vine';
|
||||
import mail from '@adonisjs/mail/services/main';
|
||||
import logger from '@adonisjs/core/services/logger';
|
||||
import { validate } from 'deep-email-validator';
|
||||
|
||||
interface Dictionary {
|
||||
[index: string]: string;
|
||||
}
|
||||
|
||||
|
||||
export default class DatasetsController {
|
||||
public async index({ auth, request, inertia }: HttpContext) {
|
||||
const user = (await User.find(auth.user?.id)) as User;
|
||||
|
@ -196,8 +198,8 @@ export default class DatasetsController {
|
|||
.where('id', id)
|
||||
// .preload('titles')
|
||||
// .preload('descriptions')
|
||||
.preload('user', (builder) => {
|
||||
builder.select('id', 'login');
|
||||
.preload('editor', (builder) => {
|
||||
builder.select('id', 'login', 'email');
|
||||
})
|
||||
.firstOrFail();
|
||||
|
||||
|
@ -218,12 +220,14 @@ export default class DatasetsController {
|
|||
});
|
||||
}
|
||||
|
||||
public async rejectUpdate({ request, response }: HttpContext) {
|
||||
public async rejectUpdate({ request, response, auth }: HttpContext) {
|
||||
const authUser = auth.user!;
|
||||
|
||||
const id = request.param('id');
|
||||
const dataset = await Dataset.query()
|
||||
.where('id', id)
|
||||
.preload('editor', (builder) => {
|
||||
builder.select('id', 'login');
|
||||
builder.select('id', 'login', 'email');
|
||||
})
|
||||
.firstOrFail();
|
||||
|
||||
|
@ -234,6 +238,7 @@ export default class DatasetsController {
|
|||
const newSchema = vine.object({
|
||||
server_state: vine.string().trim(),
|
||||
reject_reviewer_note: vine.string().trim().minLength(10).maxLength(500),
|
||||
send_mail: vine.boolean().optional(),
|
||||
});
|
||||
|
||||
try {
|
||||
|
@ -250,9 +255,9 @@ export default class DatasetsController {
|
|||
// throw new Error('Invalid server state!');
|
||||
// return response.flash('warning', 'Invalid server state. Dataset cannot be released to editor').redirect().back();
|
||||
return response
|
||||
.flash(
|
||||
'warning',
|
||||
.flash(
|
||||
`Invalid server state. Dataset with id ${id} cannot be rejected. Datset has server state ${dataset.server_state}.`,
|
||||
'warning',
|
||||
)
|
||||
.redirect()
|
||||
.toRoute('reviewer.dataset.list');
|
||||
|
@ -263,16 +268,43 @@ export default class DatasetsController {
|
|||
const rejectReviewerNote = request.input('reject_reviewer_note', '');
|
||||
dataset.reject_reviewer_note = rejectReviewerNote;
|
||||
|
||||
try {
|
||||
// await dataset.related('editor').associate(user); // speichert schon ab
|
||||
await dataset.save();
|
||||
return response
|
||||
.toRoute('reviewer.dataset.list')
|
||||
.flash('message', `You have rejected dataset ${dataset.id}! to editor ${dataset.editor.login}`);
|
||||
} catch (error) {
|
||||
// Handle any errors
|
||||
console.error(error);
|
||||
return response.status(500).json({ error: 'An error occurred while reviewing the data.' });
|
||||
// add logic for sending reject message
|
||||
const sendMail = request.input('send_email', false);
|
||||
// const validRecipientEmail = await this.checkEmailDomain('arno.kaimbacher@outlook.at');
|
||||
const validationResult = await validate({
|
||||
email: dataset.editor.email,
|
||||
validateSMTP: false,
|
||||
});
|
||||
const validRecipientEmail: boolean = validationResult.valid;
|
||||
let emailStatusMessage = '';
|
||||
|
||||
if (sendMail == true) {
|
||||
if (dataset.user.email && validRecipientEmail) {
|
||||
try {
|
||||
await mail.send((message) => {
|
||||
message.to(dataset.editor.email).subject('Dataset Rejection Notification').html(`
|
||||
<p>Dear editor ${dataset.editor.login},</p>
|
||||
<p>Your approved dataset with ID ${dataset.id} has been rejected.</p>
|
||||
<p>Reason for rejection: ${rejectReviewerNote}</p>
|
||||
<p>Best regards,<br>Your Tethys reviewer: ${authUser.login}</p>
|
||||
`);
|
||||
});
|
||||
emailStatusMessage = ` A rejection email was successfully sent to ${dataset.editor.email}.`;
|
||||
} catch (error) {
|
||||
logger.error(error);
|
||||
return response
|
||||
.flash('Dataset has not been rejected due to an email error: ' + error.message, 'error')
|
||||
.toRoute('reviewer.dataset.list');
|
||||
}
|
||||
} else {
|
||||
emailStatusMessage = ` However, the email could not be sent because the editor's email address (${dataset.editor.email}) is not valid.`;
|
||||
}
|
||||
}
|
||||
|
||||
await dataset.save();
|
||||
|
||||
return response
|
||||
.toRoute('reviewer.dataset.list')
|
||||
.flash(`You have rejected dataset ${dataset.id}! to editor ${dataset.editor.login}`, 'message');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -771,7 +771,7 @@ export default class DatasetController {
|
|||
}
|
||||
|
||||
if (await dataset.merge(input).save()) {
|
||||
return response.toRoute('dataset.list').flash('message', 'You have released your dataset!');
|
||||
return response.toRoute('dataset.list').flash('You have released your dataset!', 'message');
|
||||
}
|
||||
// throw new GeneralException(trans('exceptions.publish.release.update_error'));
|
||||
}
|
||||
|
|
Loading…
Add table
editor.link_modal.header
Reference in a new issue