You've already forked joplin
mirror of
https://github.com/laurent22/joplin.git
synced 2025-07-13 00:10:37 +02:00
Server: Moved email templates to separate files
This commit is contained in:
@ -11,6 +11,11 @@ export interface EmailToSend {
|
|||||||
recipient_id?: Uuid;
|
recipient_id?: Uuid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface EmailSubjectBody {
|
||||||
|
subject: string;
|
||||||
|
body: string;
|
||||||
|
}
|
||||||
|
|
||||||
export default class EmailModel extends BaseModel<Email> {
|
export default class EmailModel extends BaseModel<Email> {
|
||||||
|
|
||||||
public get tableName(): string {
|
public get tableName(): string {
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import { EmailSender, Subscription, Uuid } from '../db';
|
import { EmailSender, Subscription, Uuid } from '../db';
|
||||||
import { ErrorNotFound } from '../utils/errors';
|
import { ErrorNotFound } from '../utils/errors';
|
||||||
import uuidgen from '../utils/uuidgen';
|
import uuidgen from '../utils/uuidgen';
|
||||||
|
import paymentFailedTemplate from '../views/emails/paymentFailedTemplate';
|
||||||
import BaseModel from './BaseModel';
|
import BaseModel from './BaseModel';
|
||||||
import { AccountType } from './UserModel';
|
import { AccountType } from './UserModel';
|
||||||
|
|
||||||
@ -27,12 +28,13 @@ export default class SubscriptionModel extends BaseModel<Subscription> {
|
|||||||
} else {
|
} else {
|
||||||
toSave.last_payment_failed_time = now;
|
toSave.last_payment_failed_time = now;
|
||||||
|
|
||||||
const user = await this.models().user().load(sub.user_id, { fields: ['email'] });
|
const user = await this.models().user().load(sub.user_id, { fields: ['email', 'id', 'full_name'] });
|
||||||
|
|
||||||
await this.models().email().push({
|
await this.models().email().push({
|
||||||
subject: `${this.appName} subscription payment failed`,
|
...paymentFailedTemplate(),
|
||||||
body: `Hello,\n\nWe were not able to process your last payment. Please follow this URL to update your payment details: \n\n[Manage your subscription](${this.baseUrl}/portal)\n\nPlease answer this email if you have any question.\n\nThank you,\n\nJoplin Cloud Team`,
|
|
||||||
recipient_email: user.email,
|
recipient_email: user.email,
|
||||||
|
recipient_id: user.id,
|
||||||
|
recipient_name: user.full_name || '',
|
||||||
sender_id: EmailSender.Support,
|
sender_id: EmailSender.Support,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,8 @@ import { getMaxItemSize, getMaxTotalItemSize } from './utils/user';
|
|||||||
import * as zxcvbn from 'zxcvbn';
|
import * as zxcvbn from 'zxcvbn';
|
||||||
import { confirmUrl, resetPasswordUrl } from '../utils/urlUtils';
|
import { confirmUrl, resetPasswordUrl } from '../utils/urlUtils';
|
||||||
import { checkRepeatPassword, CheckRepeatPasswordInput } from '../routes/index/users';
|
import { checkRepeatPassword, CheckRepeatPasswordInput } from '../routes/index/users';
|
||||||
|
import accountConfirmationTemplate from '../views/emails/accountConfirmationTemplate';
|
||||||
|
import resetPasswordTemplate from '../views/emails/resetPasswordTemplate';
|
||||||
|
|
||||||
export enum AccountType {
|
export enum AccountType {
|
||||||
Default = 0,
|
Default = 0,
|
||||||
@ -253,12 +255,11 @@ export default class UserModel extends BaseModel<User> {
|
|||||||
const url = encodeURI(confirmUrl(user.id, validationToken));
|
const url = encodeURI(confirmUrl(user.id, validationToken));
|
||||||
|
|
||||||
await this.models().email().push({
|
await this.models().email().push({
|
||||||
|
...accountConfirmationTemplate({ url }),
|
||||||
sender_id: EmailSender.NoReply,
|
sender_id: EmailSender.NoReply,
|
||||||
recipient_id: user.id,
|
recipient_id: user.id,
|
||||||
recipient_email: user.email,
|
recipient_email: user.email,
|
||||||
recipient_name: user.full_name || '',
|
recipient_name: user.full_name || '',
|
||||||
subject: `Please setup your ${this.appName} account`,
|
|
||||||
body: `Your new ${this.appName} account is almost ready to use!\n\nPlease click on the following link to finish setting up your account:\n\n[Complete your account](${url})`,
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -270,12 +271,11 @@ export default class UserModel extends BaseModel<User> {
|
|||||||
const url = resetPasswordUrl(validationToken);
|
const url = resetPasswordUrl(validationToken);
|
||||||
|
|
||||||
await this.models().email().push({
|
await this.models().email().push({
|
||||||
|
...resetPasswordTemplate({ url }),
|
||||||
sender_id: EmailSender.NoReply,
|
sender_id: EmailSender.NoReply,
|
||||||
recipient_id: user.id,
|
recipient_id: user.id,
|
||||||
recipient_email: user.email,
|
recipient_email: user.email,
|
||||||
recipient_name: user.full_name || '',
|
recipient_name: user.full_name || '',
|
||||||
subject: `Reset your ${this.appName} password`,
|
|
||||||
body: `Somebody asked to reset your password on ${this.appName}\n\nIf it was not you, you can safely ignore this email.\n\nClick the following link to choose a new password:\n\n${url}`,
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,3 +30,7 @@ export function profileUrl(): string {
|
|||||||
export function confirmUrl(userId: Uuid, validationToken: string): string {
|
export function confirmUrl(userId: Uuid, validationToken: string): string {
|
||||||
return `${config().baseUrl}/users/${userId}/confirm?token=${validationToken}`;
|
return `${config().baseUrl}/users/${userId}/confirm?token=${validationToken}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function stripePortalUrl(): string {
|
||||||
|
return `${config().baseUrl}/stripe/portal`;
|
||||||
|
}
|
||||||
|
@ -0,0 +1,20 @@
|
|||||||
|
import markdownUtils from '@joplin/lib/markdownUtils';
|
||||||
|
import config from '../../config';
|
||||||
|
import { EmailSubjectBody } from '../../models/EmailModel';
|
||||||
|
|
||||||
|
interface TemplateView {
|
||||||
|
url: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default (view: TemplateView): EmailSubjectBody => {
|
||||||
|
return {
|
||||||
|
subject: `Your new ${config().appName} account is almost ready to use`,
|
||||||
|
body: `
|
||||||
|
|
||||||
|
Please click on the following link to finish setting up your account:
|
||||||
|
|
||||||
|
[Complete your account](${markdownUtils.escapeLinkUrl(view.url)})
|
||||||
|
|
||||||
|
`.trim(),
|
||||||
|
};
|
||||||
|
};
|
24
packages/server/src/views/emails/paymentFailedTemplate.ts
Normal file
24
packages/server/src/views/emails/paymentFailedTemplate.ts
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
import markdownUtils from '@joplin/lib/markdownUtils';
|
||||||
|
import config from '../../config';
|
||||||
|
import { EmailSubjectBody } from '../../models/EmailModel';
|
||||||
|
import { stripePortalUrl } from '../../utils/urlUtils';
|
||||||
|
|
||||||
|
export default function(): EmailSubjectBody {
|
||||||
|
return {
|
||||||
|
subject: `${config().appName} subscription payment failed`,
|
||||||
|
body: `
|
||||||
|
Hello,
|
||||||
|
|
||||||
|
We were not able to process your last payment. Please follow this URL to update your payment details:
|
||||||
|
|
||||||
|
[Manage your subscription](${markdownUtils.escapeLinkUrl(stripePortalUrl())})
|
||||||
|
|
||||||
|
Please answer this email if you have any question.
|
||||||
|
|
||||||
|
Thank you,
|
||||||
|
|
||||||
|
Joplin Cloud Team
|
||||||
|
`
|
||||||
|
.trim(),
|
||||||
|
};
|
||||||
|
}
|
23
packages/server/src/views/emails/resetPasswordTemplate.ts
Normal file
23
packages/server/src/views/emails/resetPasswordTemplate.ts
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
import config from '../../config';
|
||||||
|
import { EmailSubjectBody } from '../../models/EmailModel';
|
||||||
|
|
||||||
|
interface TemplateView {
|
||||||
|
url: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function(view: TemplateView): EmailSubjectBody {
|
||||||
|
return {
|
||||||
|
subject: `Reset your ${config().appName} password`,
|
||||||
|
body: `
|
||||||
|
|
||||||
|
Somebody asked to reset your password on ${config().appName}.
|
||||||
|
|
||||||
|
If it was not you, you can safely ignore this email.
|
||||||
|
|
||||||
|
Click the following link to choose a new password:
|
||||||
|
|
||||||
|
${view.url}
|
||||||
|
|
||||||
|
`.trim(),
|
||||||
|
};
|
||||||
|
}
|
Reference in New Issue
Block a user