2019-11-08 11:56:56 +03:00
|
|
|
import Component from '@ember/component';
|
2019-11-25 16:20:16 +03:00
|
|
|
import EmailFailedError from 'ghost-admin/errors/email-failed-error';
|
2022-02-01 12:34:03 +03:00
|
|
|
import classic from 'ember-classic-decorator';
|
2019-11-08 11:56:56 +03:00
|
|
|
import validator from 'validator';
|
2022-02-01 12:34:03 +03:00
|
|
|
import {action, computed} from '@ember/object';
|
2020-07-03 12:48:54 +03:00
|
|
|
import {alias, not, oneWay, or} from '@ember/object/computed';
|
2021-05-12 14:33:36 +03:00
|
|
|
import {htmlSafe} from '@ember/template';
|
2019-11-08 11:56:56 +03:00
|
|
|
import {inject as service} from '@ember/service';
|
2019-11-25 16:20:16 +03:00
|
|
|
import {task, timeout} from 'ember-concurrency';
|
|
|
|
|
|
|
|
const RETRY_EMAIL_POLL_LENGTH = 1000;
|
|
|
|
const RETRY_EMAIL_MAX_POLL_LENGTH = 15 * 1000;
|
2019-11-08 11:56:56 +03:00
|
|
|
|
2022-02-01 12:34:03 +03:00
|
|
|
@classic
|
|
|
|
export default class Email extends Component {
|
2022-02-01 20:03:45 +03:00
|
|
|
@service ajax;
|
|
|
|
@service ghostPaths;
|
|
|
|
@service notifications;
|
|
|
|
@service session;
|
|
|
|
@service settings;
|
|
|
|
@service config;
|
2020-07-03 12:48:54 +03:00
|
|
|
|
2022-02-01 12:34:03 +03:00
|
|
|
post = null;
|
|
|
|
sendTestEmailError = '';
|
|
|
|
savePostTask = null;
|
|
|
|
close() {}
|
2019-11-08 11:56:56 +03:00
|
|
|
|
2022-02-01 12:34:03 +03:00
|
|
|
@or('emailSubjectScratch', 'post.title')
|
2022-02-10 13:41:36 +03:00
|
|
|
emailSubject;
|
2019-11-08 11:56:56 +03:00
|
|
|
|
2022-02-01 12:34:03 +03:00
|
|
|
@alias('post.emailSubjectScratch')
|
2022-02-10 13:41:36 +03:00
|
|
|
emailSubjectScratch;
|
2019-11-08 11:56:56 +03:00
|
|
|
|
2022-02-01 12:34:03 +03:00
|
|
|
@oneWay('session.user.email')
|
2022-02-10 13:41:36 +03:00
|
|
|
testEmailAddress;
|
2019-11-08 11:56:56 +03:00
|
|
|
|
2022-02-01 12:34:03 +03:00
|
|
|
@not('mailgunIsEnabled')
|
2022-02-10 13:41:36 +03:00
|
|
|
mailgunError;
|
2022-02-01 12:34:03 +03:00
|
|
|
|
|
|
|
@computed(
|
|
|
|
'settings.{mailgunApiKey,mailgunDomain,mailgunBaseUrl}',
|
|
|
|
'config.mailgunIsConfigured'
|
|
|
|
)
|
|
|
|
get mailgunIsEnabled() {
|
|
|
|
return this.get('settings.mailgunApiKey') && this.get('settings.mailgunDomain') && this.get('settings.mailgunBaseUrl') || this.get('config.mailgunIsConfigured');
|
|
|
|
}
|
2019-11-08 11:56:56 +03:00
|
|
|
|
2022-02-01 12:34:03 +03:00
|
|
|
@action
|
|
|
|
setEmailSubject(emailSubject) {
|
|
|
|
// Grab the post and current stored email subject
|
|
|
|
let post = this.post;
|
|
|
|
let currentEmailSubject = post.get('emailSubject');
|
2019-11-08 11:56:56 +03:00
|
|
|
|
2022-02-01 12:34:03 +03:00
|
|
|
// If the subject entered matches the stored email subject, do nothing
|
|
|
|
if (currentEmailSubject === emailSubject) {
|
|
|
|
return;
|
2019-11-08 11:56:56 +03:00
|
|
|
}
|
|
|
|
|
2022-02-01 12:34:03 +03:00
|
|
|
// If the subject entered is different, set it as the new email subject
|
|
|
|
post.set('emailSubject', emailSubject);
|
|
|
|
|
|
|
|
// Make sure the email subject is valid and if so, save it into the post
|
|
|
|
return post.validate({property: 'emailSubject'}).then(() => {
|
|
|
|
if (post.get('isNew')) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
return this.savePostTask.perform();
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
@action
|
|
|
|
discardEnter() {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
@(task(function* () {
|
2019-11-08 11:56:56 +03:00
|
|
|
try {
|
|
|
|
const resourceId = this.post.id;
|
2019-11-13 13:52:09 +03:00
|
|
|
const testEmail = this.testEmailAddress.trim();
|
2019-11-08 11:56:56 +03:00
|
|
|
if (!validator.isEmail(testEmail)) {
|
|
|
|
this.set('sendTestEmailError', 'Please enter a valid email');
|
|
|
|
return false;
|
|
|
|
}
|
2022-01-21 22:25:47 +03:00
|
|
|
if (!this.mailgunIsEnabled) {
|
2020-06-30 09:27:18 +03:00
|
|
|
this.set('sendTestEmailError', 'Please verify your email settings');
|
2019-11-08 11:56:56 +03:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
this.set('sendTestEmailError', '');
|
|
|
|
const url = this.ghostPaths.url.api('/email_preview/posts', resourceId);
|
|
|
|
const data = {emails: [testEmail]};
|
|
|
|
const options = {
|
|
|
|
data,
|
|
|
|
dataType: 'json'
|
|
|
|
};
|
|
|
|
return yield this.ajax.post(url, options);
|
|
|
|
} catch (error) {
|
|
|
|
if (error) {
|
2020-07-10 20:35:13 +03:00
|
|
|
let message = 'Email could not be sent, verify mail settings';
|
|
|
|
|
|
|
|
// grab custom error message if present
|
|
|
|
if (
|
|
|
|
error.payload && error.payload.errors
|
|
|
|
&& error.payload.errors[0] && error.payload.errors[0].message) {
|
|
|
|
message = htmlSafe(error.payload.errors[0].message);
|
|
|
|
}
|
|
|
|
|
|
|
|
this.set('sendTestEmailError', message);
|
2019-11-08 11:56:56 +03:00
|
|
|
}
|
|
|
|
}
|
2022-02-01 12:34:03 +03:00
|
|
|
}).drop())
|
2022-02-10 13:41:36 +03:00
|
|
|
sendTestEmail;
|
2019-11-25 16:20:16 +03:00
|
|
|
|
2022-02-01 12:34:03 +03:00
|
|
|
@task(function* () {
|
2019-11-25 16:20:16 +03:00
|
|
|
let {email} = this.post;
|
|
|
|
|
|
|
|
if (email && email.status === 'failed') {
|
|
|
|
// trigger the retry
|
|
|
|
yield email.retry();
|
|
|
|
|
|
|
|
// poll for success/failure state
|
|
|
|
let pollTimeout = 0;
|
|
|
|
while (pollTimeout < RETRY_EMAIL_MAX_POLL_LENGTH) {
|
|
|
|
yield timeout(RETRY_EMAIL_POLL_LENGTH);
|
|
|
|
yield email.reload();
|
|
|
|
|
|
|
|
if (email.status === 'submitted') {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (email.status === 'failed') {
|
|
|
|
throw new EmailFailedError(email.error);
|
|
|
|
}
|
2021-05-24 13:22:41 +03:00
|
|
|
pollTimeout += RETRY_EMAIL_POLL_LENGTH;
|
2019-11-25 16:20:16 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
})
|
2022-02-10 13:41:36 +03:00
|
|
|
retryEmail;
|
2022-02-01 12:34:03 +03:00
|
|
|
}
|