Selfservice link forgotten mails feature/5-registration_forgot_mails #10
|
@ -121,8 +121,8 @@ export class Mailer {
|
|||
|
||||
/**
|
||||
* Function for sending a reset mail from the reset mail template.
|
||||
* @param to_address The address the mail will be sent to. Should always get pulled from a user object.
|
||||
* @param token The requested password reset token - will be combined with the app_url to generate a password reset link.
|
||||
* @param to_address The address the mail will be sent to. Should always get pulled from a runner object.
|
||||
* @param token The runner's selfservice token - will be combined with the app_url to generate a selfservice profile link.
|
||||
*/
|
||||
public async sendWelcomeMail(to_address: string, token: string, locale: string = "en") {
|
||||
await i18next.changeLanguage(locale);
|
||||
|
@ -152,6 +152,39 @@ export class Mailer {
|
|||
await this.sendMail(mail);
|
||||
}
|
||||
|
||||
/**
|
||||
* Function for sending a selfservice link forgotten mail from the runner_forgot template.
|
||||
* @param to_address The address the mail will be sent to. Should always get pulled from a runner object.
|
||||
* @param token The runner's selfservice token - will be combined with the app_url to generate a selfservice profile link.
|
||||
*/
|
||||
public async sendSelfserviceForgottenMail(to_address: string, token: string, locale: string = "en") {
|
||||
await i18next.changeLanguage(locale);
|
||||
|
||||
const replacements = {
|
||||
recipient_mail: to_address,
|
||||
copyright_owner: config.copyright_owner,
|
||||
link_imprint: `${config.app_url}/imprint`,
|
||||
link_privacy: `${config.app_url}/privacy`,
|
||||
selfservice_link: `${config.app_url}/selfservice/profile/${token}`,
|
||||
forgot_link: `${config.app_url}/selfservice`,
|
||||
contact_mail: config.contact_mail,
|
||||
event_name: config.event_name
|
||||
}
|
||||
|
||||
const template_html = Handlebars.compile(fs.readFileSync(__dirname + '/templates/runner_forgot.html', { encoding: 'utf8' }));
|
||||
const template_txt = Handlebars.compile(fs.readFileSync(__dirname + '/templates/runner_forgot.txt', { encoding: 'utf8' }));
|
||||
const body_html = template_html(replacements);
|
||||
const body_txt = template_txt(replacements);
|
||||
|
||||
const mail: MailOptions = {
|
||||
to: to_address,
|
||||
subject: i18next.t("your-event_name-profile", Mailer.interpolations).toString(),
|
||||
text: body_txt,
|
||||
html: body_html
|
||||
};
|
||||
await this.sendMail(mail);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper function for sending a mail via this object's transporter.
|
||||
* @param mail MailOptions object containing the
|
||||
|
|
|
@ -2,6 +2,7 @@ import { Authorized, Body, JsonController, Post, QueryParam } from 'routing-cont
|
|||
import { OpenAPI } from 'routing-controllers-openapi';
|
||||
import { Mailer } from '../Mailer';
|
||||
import { locales } from '../models/LocaleEnum';
|
||||
import { MailTypes } from '../models/MailTypeEnum';
|
||||
import { ResetMail } from '../models/ResetMail';
|
||||
import { SuccessResponse } from '../models/SuccessResponse';
|
||||
import { WelcomeMail } from '../models/WelcomeMail';
|
||||
|
@ -28,7 +29,7 @@ export class MailController {
|
|||
} catch (error) {
|
||||
throw error;
|
||||
}
|
||||
return new SuccessResponse(locale);
|
||||
return new SuccessResponse(MailTypes.PASSWORD_RESET, locale);
|
||||
}
|
||||
|
||||
@Post('/test')
|
||||
|
@ -44,7 +45,7 @@ export class MailController {
|
|||
console.log(error)
|
||||
throw error;
|
||||
}
|
||||
return new SuccessResponse(locale);
|
||||
return new SuccessResponse(MailTypes.TEST, locale);
|
||||
}
|
||||
|
||||
@Post('/registration')
|
||||
|
@ -60,6 +61,22 @@ export class MailController {
|
|||
console.log(error)
|
||||
throw error;
|
||||
}
|
||||
return new SuccessResponse(locale);
|
||||
return new SuccessResponse(MailTypes.RUNNER_WELCOME, locale);
|
||||
}
|
||||
|
||||
@Post('/registration_forgot')
|
||||
@OpenAPI({ description: "Sends selfservice link forgotten mails", parameters: [{ in: "query", name: "locale", schema: { type: "string", enum: ["de", "en"] } }] })
|
||||
async sendSelfserviceForgotten(@Body({ validate: true }) mailOptions: WelcomeMail, @QueryParam("locale") locale: locales) {
|
||||
if (!this.initialized) {
|
||||
await this.mailer.init();
|
||||
this.initialized = true;
|
||||
}
|
||||
try {
|
||||
this.mailer.sendSelfserviceForgottenMail(mailOptions.address, mailOptions.selfserviceToken, locale?.toString())
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
throw error;
|
||||
}
|
||||
return new SuccessResponse(MailTypes.RUNNER_FORGOT, locale);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,15 +12,20 @@
|
|||
"privacy": "Privacy",
|
||||
"reset-password": "Reset password",
|
||||
"test-mail": "Test mail",
|
||||
"thank-you-for-requesting-a-new-link-to-your-event_name-runner-profile": "Thank you for requesting a new link to your {{event_name}} runner profile.",
|
||||
"thanks-for-registering-and-welcome-to-the-event_name": "Thanks for registering and welcome to the {{event_name}}!",
|
||||
"the-only-thing-you-have-to-do-now-is-to-bring-your-registration-code-with-you": "The only thing you have to do now is to bring your registration code with you.",
|
||||
"this-is-a-test-mail-triggered-by-an-admin-in-the-lfk-backend": "This is a test mail triggered by an admin in the LfK! backend.",
|
||||
"this-mail-was-sent-to-recipient_mail-because-someone-request-a-mail-test-for-this-mail-address": "This mail was sent to you because someone request a mail test for this mail address.",
|
||||
"this-mail-was-sent-to-you-because-someone-request-a-password-reset-for-a-account-linked-to-the-mail-address": "This mail was sent to you because someone request a password reset for a account linked to the mail address.",
|
||||
"this-mail-was-sent-to-you-because-someone-used-your-mail-address-to-register-themselfes-for-the-event_name": "This mail was sent to you, because someone used your mail address to register themselfes for the {{event_name}}",
|
||||
"this-mail-was-sent-to-you-because-someone-requested-a-new-link-to-access-your-profile-for-the-event_name": "This mail was sent to you, because someone requested a new link to access your profile for the {{event_name}}.",
|
||||
"this-mail-was-sent-to-you-because-someone-used-your-mail-address-to-register-themselfes-for-the-event_name": "This mail was sent to you, because someone used your mail address to register themselves for the {{event_name}}",
|
||||
niggl marked this conversation as resolved
Outdated
|
||||
"to-prevent-spam-you-can-only-request-a-new-link-every-24hrs": "To prevent spam you can only request a new link every 24hrs.",
|
||||
"view-my-data": "View my data",
|
||||
"we-successfully-processed-your-registration": "We successfully processed your registration.",
|
||||
"welcome": "Welcome",
|
||||
"you-can-view-your-registration-code-lap-times-and-much-more-by-visiting-our-selfservice": "You can view your registration code, lap times and much more by visiting our selfservice:",
|
||||
"your-password-wont-be-changed-until-you-click-the-reset-link-below-and-set-a-new-one": "Your password won't be changed until you click the reset link below and set a new one."
|
||||
"your-event_name-profile": "Your {{event_name}} profile",
|
||||
"your-password-wont-be-changed-until-you-click-the-reset-link-below-and-set-a-new-one": "Your password won't be changed until you click the reset link below and set a new one.",
|
||||
"your-profile": "Your Profile"
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
export enum MailTypes {
|
||||
PASSWORD_RESET = "PASSWORD_RESET",
|
||||
RUNNER_FORGOT = "RUNNER_FORGOT",
|
||||
RUNNER_WELCOME = "RUNNER_WELCOME",
|
||||
TEST = "TEST"
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
import { IsBoolean, IsString } from 'class-validator';
|
||||
import { locales } from './LocaleEnum';
|
||||
import { MailTypes } from './MailTypeEnum';
|
||||
|
||||
/**
|
||||
* Simple success response class to make everyone happy :)
|
||||
|
@ -15,7 +16,11 @@ export class SuccessResponse {
|
|||
@IsString()
|
||||
locale: locales;
|
||||
|
||||
constructor(locale?: locales) {
|
||||
@IsString()
|
||||
type: MailTypes;
|
||||
|
||||
constructor(type: MailTypes, locale?: locales) {
|
||||
this.type = type;
|
||||
this.locale = locale || locales.en;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,396 @@
|
|||
|
||||
<!DOCTYPE html>
|
||||
<html lang="de" xmlns="http://www.w3.org/1999/xhtml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:v="urn:schemas-microsoft-com:vml">
|
||||
<head>
|
||||
<title>{{__ "your-event_name-profile"}}<title> <!-- The title tag shows in email notifications, like Android 4.4. -->
|
||||
<meta charset="utf-8"> <!-- utf-8 works for most cases -->
|
||||
<meta http-equiv="Content-Type" content="text/html charset=UTF-8" />
|
||||
<meta name="viewport" content="width=device-width"> <!-- Forcing initial-scale shouldn't be necessary -->
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <!-- Use the latest (edge) version of IE rendering engine -->
|
||||
<meta name="x-apple-disable-message-reformatting"> <!-- Disable auto-scale in iOS 10 Mail entirely -->
|
||||
<meta name="format-detection" content="telephone=no,address=no,email=no,date=no,url=no"> <!-- Tell iOS not to automatically link certain text strings. -->
|
||||
|
||||
<!-- CSS Reset : BEGIN -->
|
||||
<style>
|
||||
/* What it does: Remove spaces around the email design added by some email clients. */
|
||||
/* Beware: It can remove the padding / margin and add a background color to the compose a reply window. */
|
||||
html,
|
||||
body {
|
||||
margin: 0 auto !important;
|
||||
padding: 0 !important;
|
||||
height: 100% !important;
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
/* What it does: Stops email clients resizing small text. */
|
||||
* {
|
||||
-ms-text-size-adjust: 100%;
|
||||
-webkit-text-size-adjust: 100%;
|
||||
}
|
||||
|
||||
/* What it does: Centers email on Android 4.4 */
|
||||
div[style*="margin: 16px 0"] {
|
||||
margin:0 !important;
|
||||
}
|
||||
|
||||
/* What it does: Stops Outlook from adding extra spacing to tables. */
|
||||
table,
|
||||
td {
|
||||
mso-table-lspace: 0pt !important;
|
||||
mso-table-rspace: 0pt !important;
|
||||
}
|
||||
|
||||
/* What it does: Fixes webkit padding issue. */
|
||||
table {
|
||||
border: 0;
|
||||
border-spacing: 0;
|
||||
border-collapse: collapse
|
||||
}
|
||||
|
||||
/* What it does: Forces Samsung Android mail clients to use the entire viewport. */
|
||||
#MessageViewBody,
|
||||
#MessageWebViewDiv{
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
/* What it does: Uses a better rendering method when resizing images in IE. */
|
||||
img {
|
||||
-ms-interpolation-mode:bicubic;
|
||||
}
|
||||
|
||||
/* What it does: Prevents Windows 10 Mail from underlining links despite inline CSS. Styles for underlined links should be inline. */
|
||||
a {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
/* What it does: A work-around for email clients automatically linking certain text strings. */
|
||||
/* iOS */
|
||||
a[x-apple-data-detectors],
|
||||
.unstyle-auto-detected-links a,
|
||||
.aBn {
|
||||
border-bottom: 0 !important;
|
||||
cursor: default !important;
|
||||
color: inherit !important;
|
||||
text-decoration: none !important;
|
||||
font-size: inherit !important;
|
||||
font-family: inherit !important;
|
||||
font-weight: inherit !important;
|
||||
line-height: inherit !important;
|
||||
}
|
||||
u + #body a, /* Gmail */
|
||||
#MessageViewBody a /* Samsung Mail */
|
||||
{
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
font-size: inherit;
|
||||
font-family: inherit;
|
||||
font-weight: inherit;
|
||||
line-height: inherit;
|
||||
}
|
||||
|
||||
/* What it does: Prevents Gmail from changing the text color in conversation threads. */
|
||||
.im {
|
||||
color: inherit !important;
|
||||
}
|
||||
|
||||
/* What it does: Prevents Gmail from displaying an download button on large, non-linked images. */
|
||||
.a6S {
|
||||
display: none !important;
|
||||
opacity: 0.01 !important;
|
||||
}
|
||||
/* If the above doesn't work, add a .g-img class to any image in question. */
|
||||
img.g-img + div {
|
||||
display:none !important;
|
||||
}
|
||||
|
||||
/* What it does: Removes right gutter in Gmail iOS app: https://github.com/TedGoas/Cerberus/issues/89 */
|
||||
/* Create one of these media queries for each additional viewport size you'd like to fix */
|
||||
|
||||
/* iPhone 4, 4S, 5, 5S, 5C, and 5SE */
|
||||
@media only screen and (min-device-width: 320px) and (max-device-width: 374px) {
|
||||
u ~ div .email-container {
|
||||
min-width: 320px !important;
|
||||
}
|
||||
}
|
||||
/* iPhone 6, 6S, 7, 8, and X */
|
||||
@media only screen and (min-device-width: 375px) and (max-device-width: 413px) {
|
||||
u ~ div .email-container {
|
||||
min-width: 375px !important;
|
||||
}
|
||||
}
|
||||
/* iPhone 6+, 7+, and 8+ */
|
||||
@media only screen and (min-device-width: 414px) {
|
||||
u ~ div .email-container {
|
||||
min-width: 414px !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<!-- What it does: Helps DPI scaling in Outlook 2007-2013 -->
|
||||
<!--[if gte mso 9]>
|
||||
<xml>
|
||||
<o:OfficeDocumentSettings>
|
||||
<o:AllowPNG/>
|
||||
<o:PixelsPerInch>96</o:PixelsPerInch>
|
||||
</o:OfficeDocumentSettings>
|
||||
</xml>
|
||||
<![endif]-->
|
||||
|
||||
<!-- CSS Reset : END -->
|
||||
|
||||
<!-- Progressive Enhancements : BEGIN -->
|
||||
<style>
|
||||
/* What it does: Hover styles for buttons and tags */
|
||||
.s-btn__primary:hover {
|
||||
background: #0077CC !important;
|
||||
border-color: #0077CC !important;
|
||||
}
|
||||
.s-btn__white:hover {
|
||||
background: #EFF0F1 !important;
|
||||
border-color: #EFF0F1 !important;
|
||||
}
|
||||
.s-btn__outlined:hover {
|
||||
background: rgba(0,119,204,.05) !important;
|
||||
color: #005999 !important;
|
||||
}
|
||||
.s-tag:hover,
|
||||
.post-tag:hover {
|
||||
border-color: #cee0ed !important;
|
||||
background: #cee0ed !important;
|
||||
}
|
||||
|
||||
/* What it does: Styles markdown links that we can't write inline CSS for. */
|
||||
.has-markdown a,
|
||||
.has-markdown a:visited {
|
||||
color: #0077CC !important;
|
||||
text-decoration: none !important;
|
||||
}
|
||||
|
||||
/* What it does: Styles markdown code blocks that we can't write inline CSS for. */
|
||||
code {
|
||||
padding: 1px 5px;
|
||||
background-color: #EFF0F1;
|
||||
color: #242729;
|
||||
font-size: 13px;
|
||||
line-height: inherit;
|
||||
font-family: Consolas, Menlo, Monaco, Lucida Console, Liberation Mono, DejaVu Sans Mono, Bitstream Vera Sans Mono, Courier New, monospace, sans-serif;
|
||||
}
|
||||
pre {
|
||||
margin: 0 0 15px;
|
||||
line-height: 17px;
|
||||
background-color: #EFF0F1;
|
||||
padding: 4px 8px;
|
||||
border-radius: 3px;
|
||||
overflow-x: auto;
|
||||
}
|
||||
pre code {
|
||||
margin: 0 0 15px;
|
||||
padding: 0;
|
||||
line-height: 17px;
|
||||
background-color: none;
|
||||
}
|
||||
|
||||
/* What it does: Styles markdown blockquotes that we can't write inline CSS for. */
|
||||
blockquote {
|
||||
margin: 0 0 15px;
|
||||
padding: 4px 10px;
|
||||
background-color: #FFF8DC;
|
||||
border-left: 2px solid #ffeb8e;
|
||||
}
|
||||
blockquote p {
|
||||
padding: 4px 0;
|
||||
margin: 0;
|
||||
overflow-wrap: break-word;
|
||||
}
|
||||
|
||||
/* What it does: Rounds corners in email clients that support it */
|
||||
.bar {
|
||||
border-radius: 5px;
|
||||
}
|
||||
.btr {
|
||||
border-top-left-radius: 5px;
|
||||
border-top-right-radius: 5px;
|
||||
}
|
||||
.bbr {
|
||||
border-bottom-left-radius: 5px;
|
||||
border-bottom-right-radius: 5px;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 680px) {
|
||||
/* What it does: Forces table cells into full-width rows. */
|
||||
.stack-column,
|
||||
.stack-column-center {
|
||||
display: block !important;
|
||||
width: 100% !important;
|
||||
max-width: 100% !important;
|
||||
direction: ltr !important;
|
||||
}
|
||||
/* And center justify these ones. */
|
||||
.stack-column-center {
|
||||
text-align: center !important;
|
||||
}
|
||||
|
||||
/* Hides things in small viewports. */
|
||||
.hide-on-mobile {
|
||||
display: none !important;
|
||||
max-height: 0 !important;
|
||||
overflow: hidden !important;
|
||||
visibility: hidden !important;
|
||||
}
|
||||
|
||||
/* What it does: Utility classes to reduce spacing for smaller viewports. */
|
||||
.sm-p-none {padding: 0 !important;}
|
||||
.sm-pt-none {padding-top: 0 !important;}
|
||||
.sm-pb-none {padding-bottom: 0 !important;}
|
||||
.sm-pr-none {padding-right: 0 !important;}
|
||||
.sm-pl-none {padding-left: 0 !important;}
|
||||
.sm-px-none {padding-left: 0 !important; padding-right: 0 !important;}
|
||||
.sm-py-none {padding-top: 0 !important; padding-bottom: 0 !important;}
|
||||
|
||||
.sm-p {padding: 20px !important;}
|
||||
.sm-pt {padding-top: 20px !important;}
|
||||
.sm-pb {padding-bottom: 20px !important;}
|
||||
.sm-pr {padding-right: 20px !important;}
|
||||
.sm-pl {padding-left: 20px !important;}
|
||||
.sm-px {padding-left: 20px !important; padding-right: 20px !important;}
|
||||
.sm-py {padding-top: 20px !important; padding-bottom: 20px !important;}
|
||||
.sm-mb {margin-bottom: 20px !important;}
|
||||
|
||||
/* What it does: Utility classes to kill border radius for smaller viewports. Used mainly on the email's main container(s). */
|
||||
.bar,
|
||||
.btr,
|
||||
.bbr {
|
||||
border-top-left-radius: 0;
|
||||
border-top-right-radius: 0;
|
||||
border-bottom-left-radius: 0;
|
||||
border-bottom-right-radius: 0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<!-- Progressive Enhancements : END -->
|
||||
</head>
|
||||
|
||||
<!--
|
||||
The email background color is defined in three places, just below. If you change one, remember to change the others.
|
||||
1. body tag: for most email clients
|
||||
2. center tag: for Gmail and Inbox mobile apps and web versions of Gmail, GSuite, Inbox, Yahoo, AOL, Libero, Comcast, freenet, Mail.ru, Orange.fr
|
||||
3. mso conditional: For Windows 10 Mail
|
||||
-->
|
||||
<body width="100%" style="margin: 0; padding: 0 !important; background: #f3f3f5; mso-line-height-rule: exactly;">
|
||||
<center style="width: 100%; background: #f3f3f5;">
|
||||
<!--[if mso | IE]>
|
||||
<table role="presentation" border="0" cellpadding="0" cellspacing="0" width="100%" style="background-color: #f3f3f5;">
|
||||
<tr>
|
||||
<td>
|
||||
<![endif]-->
|
||||
|
||||
<!-- Visually Hidden Preview Text : BEGIN -->
|
||||
<div style="display: none; font-size: 1px; line-height: 1px; max-height: 0px; max-width: 0px; opacity: 0; overflow: hidden; mso-hide: all; font-family: sans-serif;">
|
||||
{{__ "your-event_name-profile"}}
|
||||
</div>
|
||||
<!-- Visually Hidden Preview Text : END -->
|
||||
|
||||
<div class="email-container" style="max-width: 680px; margin: 0 auto;">
|
||||
<!--[if mso]>
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="680" align="center">
|
||||
<tr>
|
||||
<td>
|
||||
<![endif]-->
|
||||
<table border="0" cellpadding="0" cellspacing="0" role="presentation" style="max-width: 680px; width:100%">
|
||||
<tr>
|
||||
<td style="padding: 30px; background-color: #ffffff;" class="sm-p bar">
|
||||
<table border="0" cellpadding="0" cellspacing="0" role="presentation" style="width:100%;">
|
||||
<tr>
|
||||
<td style="padding-bottom: 15px; font-family: arial, sans-serif; font-size: 15px; line-height: 21px; color: #3C3F44; text-align: left;">
|
||||
<h1 style="font-weight: bold; font-size: 27px; line-height: 27px; color: #0C0D0E; margin: 0 0 15px 0;">{{event_name}}</h1>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="padding-bottom: 15px; font-family: arial, sans-serif; font-size: 15px; line-height: 21px; color: #3C3F44; text-align: left;">
|
||||
<h1 style="font-weight: bold; font-size: 21px; line-height: 21px; color: #0C0D0E; margin: 0 0 15px 0;">{{__ "your-profile"}}</h1>
|
||||
<p style="margin: 0 0 15px;" class="has-markdown">
|
||||
{{__ "thank-you-for-requesting-a-new-link-to-your-event_name-runner-profile"}}<br>
|
||||
{{__ "you-can-view-your-registration-code-lap-times-and-much-more-by-visiting-our-selfservice"}}
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<!-- Button Row : BEGIN -->
|
||||
<tr>
|
||||
<td>
|
||||
<!-- Button : BEGIN -->
|
||||
<table align="left" border="0" cellpadding="0" cellspacing="0" role="presentation">
|
||||
<tr>
|
||||
<td class="s-btn s-btn__primary" style="border-radius: 4px; background: #0095ff;">
|
||||
<a class="s-btn s-btn__primary" href="{{selfservice_link}}" target="_parent" style="background: #0095FF; border: 1px solid #0077cc; box-shadow: inset 0 1px 0 0 rgba(102,191,255,.75); font-family: arial, sans-serif; font-size: 17px; line-height: 17px; color: #ffffff; text-align: center; text-decoration: none; padding: 13px 17px; display: block; border-radius: 4px; white-space: nowrap;">{{__ "view-my-data"}}</a>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<!-- Button : END -->
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="padding-bottom: 15px; font-family: arial, sans-serif; font-size: 15px; line-height: 21px; color: #3C3F44; text-align: left;">
|
||||
<p>Link: <a href="{{selfservice_link}}">{{selfservice_link}}</a><br>
|
||||
{{__ "if-you-ever-loose-the-link-you-can-request-a-new-one-by-visiting-our-website"}} <a href="{{forgot_link}}">{{forgot_link}}</a></p></td>
|
||||
</tr>
|
||||
<!-- Button Row : END -->
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-----------------------------
|
||||
|
||||
EMAIL BODY : END
|
||||
|
||||
------------------------------>
|
||||
|
||||
<!-- Footer : BEGIN -->
|
||||
<tr>
|
||||
<td style="padding: 30px;" class="sm-p">
|
||||
<table align="left" border="0" cellpadding="0" cellspacing="0" role="presentation" width="100%">
|
||||
<!-- Subscription Info : BEGIN -->
|
||||
<tr>
|
||||
<td style="padding-bottom: 10px; font-size: 12px; line-height: 15px; font-family: arial, sans-serif; color: #9199A1; text-align: left;">
|
||||
Copyright © {{copyright_owner}}. {{__ "all-rights-reserved"}}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="font-size: 12px; line-height: 15px; font-family: arial, sans-serif; color: #9199A1; text-align: left;">
|
||||
<a href="{{link_imprint}}"
|
||||
style="color: #9199A1; text-decoration: underline;">{{__ "imprint"}}</a>
|
||||
<a href="{{link_privacy}}" style="color: #9199A1; text-decoration: underline;">{{__ "privacy"}}</a>
|
||||
</td>
|
||||
</tr>
|
||||
<!-- Subscription Info : BEGIN -->
|
||||
<!-- HR line : BEGIN -->
|
||||
<tr>
|
||||
<td style="padding: 30px 0;" width="100%" class="sm-py">
|
||||
<table aria-hidden="true" border="0" cellpadding="0" cellspacing="0" role="presentation" style="width:100%">
|
||||
<tr>
|
||||
<td height="1" width="100%" style="font-size: 0; line-height: 0; border-top: 1px solid #D6D8DB;"> </td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
<!-- HR line : END -->
|
||||
<tr>
|
||||
<td style="padding-bottom: 5px; font-size: 12px; line-height: 15px; font-family: arial, sans-serif; color: #9199A1; text-align: left;">
|
||||
{{__ "this-mail-was-sent-to-you-because-someone-requested-a-new-link-to-access-your-profile-for-the-event_name"}}<br>
|
||||
{{__ "to-prevent-spam-you-can-only-request-a-new-link-every-24hrs"}}<br>
|
||||
{{__ "if-you-didnt-register-yourself-you-should-contact-us-to-get-your-data-removed-from-our-systems"}} <a href="mailto:{{contact_mail}}">{{contact_mail}}</a>
|
||||
</td>
|
||||
</tr>
|
||||
<!-- Sender Info : END -->
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
<!-- Footer : END -->
|
||||
</table>
|
||||
</div>
|
||||
<!--[if mso | IE]>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<![endif]-->
|
||||
</center>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,15 @@
|
|||
{{__ "your-event_name-profile"}}
|
||||
|
||||
{{__ "thank-you-for-requesting-a-new-link-to-your-event_name-runner-profile"}}
|
||||
{{__ "you-can-view-your-registration-code-lap-times-and-much-more-by-visiting-our-selfservice"}}
|
||||
|
||||
{{selfservice_link}}
|
||||
|
||||
{{__ "if-you-ever-loose-the-link-you-can-request-a-new-one-by-visiting-our-website"}} {{forgot_link}}
|
||||
|
||||
|
||||
Copyright © {{copyright_owner}}. {{__ "all-rights-reserved"}}.
|
||||
{{__ "imprint"}}: {{link_imprint}} | {{__ "privacy"}}: {{link_privacy}}
|
||||
{{__ "this-mail-was-sent-to-you-because-someone-requested-a-new-link-to-access-your-profile-for-the-event_name"}}
|
||||
{{__ "to-prevent-spam-you-can-only-request-a-new-link-every-24hrs"}}
|
||||
{{__ "if-you-didnt-register-yourself-you-should-contact-us-to-get-your-data-removed-from-our-systems"}} {{contact_mail}}
|
|
@ -42,7 +42,8 @@ describe('POST /reset with auth and vaild body', () => {
|
|||
expect(res.data).toEqual({
|
||||
success: true,
|
||||
message: "Sent!",
|
||||
locale: "en"
|
||||
locale: "en",
|
||||
type: "PASSWORD_RESET"
|
||||
})
|
||||
});
|
||||
it('Post with auth, body and locale=en should return 200', async () => {
|
||||
|
@ -54,7 +55,8 @@ describe('POST /reset with auth and vaild body', () => {
|
|||
expect(res.data).toEqual({
|
||||
success: true,
|
||||
message: "Sent!",
|
||||
locale: "en"
|
||||
locale: "en",
|
||||
type: "PASSWORD_RESET"
|
||||
})
|
||||
});
|
||||
it('Post with auth, body and locale=de should return 200', async () => {
|
||||
|
@ -66,7 +68,8 @@ describe('POST /reset with auth and vaild body', () => {
|
|||
expect(res.data).toEqual({
|
||||
success: true,
|
||||
message: "Sent!",
|
||||
locale: "de"
|
||||
locale: "de",
|
||||
type: "PASSWORD_RESET"
|
||||
})
|
||||
});
|
||||
});
|
|
@ -0,0 +1,75 @@
|
|||
import axios from 'axios';
|
||||
import { config } from '../config';
|
||||
const base = "http://localhost:" + config.internal_port
|
||||
|
||||
const axios_config = {
|
||||
validateStatus: undefined
|
||||
};
|
||||
|
||||
describe('POST /registration_forgot without auth', () => {
|
||||
it('Post without auth should return 401', async () => {
|
||||
const res = await axios.post(base + '/registration_forgot', null, axios_config);
|
||||
expect(res.status).toEqual(401);
|
||||
});
|
||||
});
|
||||
|
||||
describe('POST /registration_forgot with auth but wrong body', () => {
|
||||
it('Post with auth but no body should return 400', async () => {
|
||||
const res = await axios.post(base + '/registration_forgot?key=' + config.api_key, null, axios_config);
|
||||
expect(res.status).toEqual(400);
|
||||
});
|
||||
it('Post with auth but no mail should return 400', async () => {
|
||||
const res = await axios.post(base + '/registration_forgot?key=' + config.api_key, { selfserviceToken: "test" }, axios_config);
|
||||
expect(res.status).toEqual(400);
|
||||
});
|
||||
it('Post with auth but no reset key should return 400', async () => {
|
||||
const res = await axios.post(base + '/registration_forgot?key=' + config.api_key, { address: "test@dev.lauf-fuer-kaya.de" }, axios_config);
|
||||
expect(res.status).toEqual(400);
|
||||
});
|
||||
it('Post with auth but invalid mail should return 400', async () => {
|
||||
const res = await axios.post(base + '/registration_forgot?key=' + config.api_key, { selfserviceToken: "test", address: "testdev.l.de" }, axios_config);
|
||||
expect(res.status).toEqual(400);
|
||||
});
|
||||
});
|
||||
|
||||
describe('POST /reset with auth and vaild body', () => {
|
||||
it('Post with auth, body and no locale should return 200', async () => {
|
||||
const res = await axios.post(base + '/registration_forgot?key=' + config.api_key, {
|
||||
selfserviceToken: "test",
|
||||
address: "test@dev.lauf-fuer-kaya.de"
|
||||
}, axios_config);
|
||||
expect(res.status).toEqual(200);
|
||||
expect(res.data).toEqual({
|
||||
success: true,
|
||||
message: "Sent!",
|
||||
locale: "en",
|
||||
type: "RUNNER_FORGOT"
|
||||
})
|
||||
});
|
||||
it('Post with auth, body and locale=en should return 200', async () => {
|
||||
const res = await axios.post(base + '/registration_forgot?locale=en&key=' + config.api_key, {
|
||||
selfserviceToken: "test",
|
||||
address: "test@dev.lauf-fuer-kaya.de"
|
||||
}, axios_config);
|
||||
expect(res.status).toEqual(200);
|
||||
expect(res.data).toEqual({
|
||||
success: true,
|
||||
message: "Sent!",
|
||||
locale: "en",
|
||||
type: "RUNNER_FORGOT"
|
||||
})
|
||||
});
|
||||
it('Post with auth, body and locale=de should return 200', async () => {
|
||||
const res = await axios.post(base + '/registration_forgot?locale=de&key=' + config.api_key, {
|
||||
selfserviceToken: "test",
|
||||
address: "test@dev.lauf-fuer-kaya.de"
|
||||
}, axios_config);
|
||||
expect(res.status).toEqual(200);
|
||||
expect(res.data).toEqual({
|
||||
success: true,
|
||||
message: "Sent!",
|
||||
locale: "de",
|
||||
type: "RUNNER_FORGOT"
|
||||
})
|
||||
});
|
||||
});
|
|
@ -42,7 +42,8 @@ describe('POST /reset with auth and vaild body', () => {
|
|||
expect(res.data).toEqual({
|
||||
success: true,
|
||||
message: "Sent!",
|
||||
locale: "en"
|
||||
locale: "en",
|
||||
type: "RUNNER_WELCOME"
|
||||
})
|
||||
});
|
||||
it('Post with auth, body and locale=en should return 200', async () => {
|
||||
|
@ -54,7 +55,8 @@ describe('POST /reset with auth and vaild body', () => {
|
|||
expect(res.data).toEqual({
|
||||
success: true,
|
||||
message: "Sent!",
|
||||
locale: "en"
|
||||
locale: "en",
|
||||
type: "RUNNER_WELCOME"
|
||||
})
|
||||
});
|
||||
it('Post with auth, body and locale=de should return 200', async () => {
|
||||
|
@ -66,7 +68,8 @@ describe('POST /reset with auth and vaild body', () => {
|
|||
expect(res.data).toEqual({
|
||||
success: true,
|
||||
message: "Sent!",
|
||||
locale: "de"
|
||||
locale: "de",
|
||||
type: "RUNNER_WELCOME"
|
||||
})
|
||||
});
|
||||
});
|
|
@ -20,7 +20,8 @@ describe('POST /test with auth', () => {
|
|||
expect(res.data).toEqual({
|
||||
success: true,
|
||||
message: "Sent!",
|
||||
locale: "en"
|
||||
locale: "en",
|
||||
type: "TEST"
|
||||
})
|
||||
});
|
||||
it('Post with auth and locale=en should return 200', async () => {
|
||||
|
@ -29,7 +30,8 @@ describe('POST /test with auth', () => {
|
|||
expect(res.data).toEqual({
|
||||
success: true,
|
||||
message: "Sent!",
|
||||
locale: "en"
|
||||
locale: "en",
|
||||
type: "TEST"
|
||||
})
|
||||
});
|
||||
it('Post with auth and locale=de should return 200', async () => {
|
||||
|
@ -38,7 +40,8 @@ describe('POST /test with auth', () => {
|
|||
expect(res.data).toEqual({
|
||||
success: true,
|
||||
message: "Sent!",
|
||||
locale: "de"
|
||||
locale: "de",
|
||||
type: "TEST"
|
||||
})
|
||||
});
|
||||
});
|
Loading…
Reference in New Issue
* "themselves"