diff options
10 files changed, 42 insertions, 8 deletions
diff --git a/client/src/app/+about/about-instance/contact-admin-modal.component.html b/client/src/app/+about/about-instance/contact-admin-modal.component.html index b2cbd0873..c3c71bdee 100644 --- a/client/src/app/+about/about-instance/contact-admin-modal.component.html +++ b/client/src/app/+about/about-instance/contact-admin-modal.component.html | |||
@@ -26,6 +26,15 @@ | |||
26 | </div> | 26 | </div> |
27 | 27 | ||
28 | <div class="form-group"> | 28 | <div class="form-group"> |
29 | <label i18n for="subject">Subject</label> | ||
30 | <input | ||
31 | type="text" id="subject" | ||
32 | formControlName="subject" [ngClass]="{ 'input-error': formErrors['subject'] }" | ||
33 | > | ||
34 | <div *ngIf="formErrors.subject" class="form-error">{{ formErrors.subject }}</div> | ||
35 | </div> | ||
36 | |||
37 | <div class="form-group"> | ||
29 | <label i18n for="body">Your message</label> | 38 | <label i18n for="body">Your message</label> |
30 | <textarea id="body" formControlName="body" [ngClass]="{ 'input-error': formErrors['body'] }"> | 39 | <textarea id="body" formControlName="body" [ngClass]="{ 'input-error': formErrors['body'] }"> |
31 | </textarea> | 40 | </textarea> |
diff --git a/client/src/app/+about/about-instance/contact-admin-modal.component.ts b/client/src/app/+about/about-instance/contact-admin-modal.component.ts index 7d79c2215..c609c98c3 100644 --- a/client/src/app/+about/about-instance/contact-admin-modal.component.ts +++ b/client/src/app/+about/about-instance/contact-admin-modal.component.ts | |||
@@ -39,6 +39,7 @@ export class ContactAdminModalComponent extends FormReactive implements OnInit { | |||
39 | this.buildForm({ | 39 | this.buildForm({ |
40 | fromName: this.instanceValidatorsService.FROM_NAME, | 40 | fromName: this.instanceValidatorsService.FROM_NAME, |
41 | fromEmail: this.instanceValidatorsService.FROM_EMAIL, | 41 | fromEmail: this.instanceValidatorsService.FROM_EMAIL, |
42 | subject: this.instanceValidatorsService.SUBJECT, | ||
42 | body: this.instanceValidatorsService.BODY | 43 | body: this.instanceValidatorsService.BODY |
43 | }) | 44 | }) |
44 | } | 45 | } |
@@ -58,9 +59,10 @@ export class ContactAdminModalComponent extends FormReactive implements OnInit { | |||
58 | sendForm () { | 59 | sendForm () { |
59 | const fromName = this.form.value['fromName'] | 60 | const fromName = this.form.value['fromName'] |
60 | const fromEmail = this.form.value[ 'fromEmail' ] | 61 | const fromEmail = this.form.value[ 'fromEmail' ] |
62 | const subject = this.form.value[ 'subject' ] | ||
61 | const body = this.form.value[ 'body' ] | 63 | const body = this.form.value[ 'body' ] |
62 | 64 | ||
63 | this.instanceService.contactAdministrator(fromEmail, fromName, body) | 65 | this.instanceService.contactAdministrator(fromEmail, fromName, subject, body) |
64 | .subscribe( | 66 | .subscribe( |
65 | () => { | 67 | () => { |
66 | this.notifier.success(this.i18n('Your message has been sent.')) | 68 | this.notifier.success(this.i18n('Your message has been sent.')) |
diff --git a/client/src/app/shared/forms/form-validators/instance-validators.service.ts b/client/src/app/shared/forms/form-validators/instance-validators.service.ts index 5bb852858..cc5f3c5a1 100644 --- a/client/src/app/shared/forms/form-validators/instance-validators.service.ts +++ b/client/src/app/shared/forms/form-validators/instance-validators.service.ts | |||
@@ -7,6 +7,7 @@ import { Injectable } from '@angular/core' | |||
7 | export class InstanceValidatorsService { | 7 | export class InstanceValidatorsService { |
8 | readonly FROM_EMAIL: BuildFormValidator | 8 | readonly FROM_EMAIL: BuildFormValidator |
9 | readonly FROM_NAME: BuildFormValidator | 9 | readonly FROM_NAME: BuildFormValidator |
10 | readonly SUBJECT: BuildFormValidator | ||
10 | readonly BODY: BuildFormValidator | 11 | readonly BODY: BuildFormValidator |
11 | 12 | ||
12 | constructor (private i18n: I18n) { | 13 | constructor (private i18n: I18n) { |
@@ -32,6 +33,19 @@ export class InstanceValidatorsService { | |||
32 | } | 33 | } |
33 | } | 34 | } |
34 | 35 | ||
36 | this.SUBJECT = { | ||
37 | VALIDATORS: [ | ||
38 | Validators.required, | ||
39 | Validators.minLength(1), | ||
40 | Validators.maxLength(120) | ||
41 | ], | ||
42 | MESSAGES: { | ||
43 | 'required': this.i18n('A subject is required.'), | ||
44 | 'minlength': this.i18n('The subject must be at least 1 character long.'), | ||
45 | 'maxlength': this.i18n('The subject cannot be more than 120 characters long.') | ||
46 | } | ||
47 | } | ||
48 | |||
35 | this.BODY = { | 49 | this.BODY = { |
36 | VALIDATORS: [ | 50 | VALIDATORS: [ |
37 | Validators.required, | 51 | Validators.required, |
diff --git a/client/src/app/shared/instance/instance.service.ts b/client/src/app/shared/instance/instance.service.ts index 61321ecce..d0c96941d 100644 --- a/client/src/app/shared/instance/instance.service.ts +++ b/client/src/app/shared/instance/instance.service.ts | |||
@@ -22,10 +22,11 @@ export class InstanceService { | |||
22 | .pipe(catchError(res => this.restExtractor.handleError(res))) | 22 | .pipe(catchError(res => this.restExtractor.handleError(res))) |
23 | } | 23 | } |
24 | 24 | ||
25 | contactAdministrator (fromEmail: string, fromName: string, message: string) { | 25 | contactAdministrator (fromEmail: string, fromName: string, subject: string, message: string) { |
26 | const body = { | 26 | const body = { |
27 | fromEmail, | 27 | fromEmail, |
28 | fromName, | 28 | fromName, |
29 | subject, | ||
29 | body: message | 30 | body: message |
30 | } | 31 | } |
31 | 32 | ||
diff --git a/server/controllers/api/server/contact.ts b/server/controllers/api/server/contact.ts index b1144c94e..de02ffc0b 100644 --- a/server/controllers/api/server/contact.ts +++ b/server/controllers/api/server/contact.ts | |||
@@ -14,7 +14,7 @@ contactRouter.post('/contact', | |||
14 | async function contactAdministrator (req: express.Request, res: express.Response) { | 14 | async function contactAdministrator (req: express.Request, res: express.Response) { |
15 | const data = req.body as ContactForm | 15 | const data = req.body as ContactForm |
16 | 16 | ||
17 | await Emailer.Instance.addContactFormJob(data.fromEmail, data.fromName, data.body) | 17 | await Emailer.Instance.addContactFormJob(data.fromEmail, data.fromName, data.subject, data.body) |
18 | 18 | ||
19 | await Redis.Instance.setContactFormIp(req.ip) | 19 | await Redis.Instance.setContactFormIp(req.ip) |
20 | 20 | ||
diff --git a/server/lib/emailer.ts b/server/lib/emailer.ts index c4a5a5853..73c2bcb1b 100644 --- a/server/lib/emailer.ts +++ b/server/lib/emailer.ts | |||
@@ -402,7 +402,7 @@ class Emailer { | |||
402 | return JobQueue.Instance.createJob({ type: 'email', payload: emailPayload }) | 402 | return JobQueue.Instance.createJob({ type: 'email', payload: emailPayload }) |
403 | } | 403 | } |
404 | 404 | ||
405 | addContactFormJob (fromEmail: string, fromName: string, body: string) { | 405 | addContactFormJob (fromEmail: string, fromName: string, subject: string, body: string) { |
406 | const text = 'Hello dear admin,\n\n' + | 406 | const text = 'Hello dear admin,\n\n' + |
407 | fromName + ' sent you a message' + | 407 | fromName + ' sent you a message' + |
408 | '\n\n---------------------------------------\n\n' + | 408 | '\n\n---------------------------------------\n\n' + |
@@ -415,7 +415,7 @@ class Emailer { | |||
415 | fromDisplayName: fromEmail, | 415 | fromDisplayName: fromEmail, |
416 | replyTo: fromEmail, | 416 | replyTo: fromEmail, |
417 | to: [ CONFIG.ADMIN.EMAIL ], | 417 | to: [ CONFIG.ADMIN.EMAIL ], |
418 | subject: CONFIG.EMAIL.OBJECT.PREFIX + 'Contact form submitted', | 418 | subject: CONFIG.EMAIL.OBJECT.PREFIX + subject, |
419 | text | 419 | text |
420 | } | 420 | } |
421 | 421 | ||
diff --git a/server/tests/api/check-params/contact-form.ts b/server/tests/api/check-params/contact-form.ts index dbdd3a8a6..b3051945e 100644 --- a/server/tests/api/check-params/contact-form.ts +++ b/server/tests/api/check-params/contact-form.ts | |||
@@ -26,6 +26,7 @@ describe('Test contact form API validators', function () { | |||
26 | const defaultBody = { | 26 | const defaultBody = { |
27 | fromName: 'super name', | 27 | fromName: 'super name', |
28 | fromEmail: 'toto@example.com', | 28 | fromEmail: 'toto@example.com', |
29 | subject: 'my subject', | ||
29 | body: 'Hello, how are you?' | 30 | body: 'Hello, how are you?' |
30 | } | 31 | } |
31 | let emailPort: number | 32 | let emailPort: number |
diff --git a/server/tests/api/server/contact-form.ts b/server/tests/api/server/contact-form.ts index 87e55060c..e4e895acb 100644 --- a/server/tests/api/server/contact-form.ts +++ b/server/tests/api/server/contact-form.ts | |||
@@ -43,6 +43,7 @@ describe('Test contact form', function () { | |||
43 | url: server.url, | 43 | url: server.url, |
44 | fromEmail: 'toto@example.com', | 44 | fromEmail: 'toto@example.com', |
45 | body: 'my super message', | 45 | body: 'my super message', |
46 | subject: 'my subject', | ||
46 | fromName: 'Super toto' | 47 | fromName: 'Super toto' |
47 | }) | 48 | }) |
48 | 49 | ||
@@ -55,7 +56,7 @@ describe('Test contact form', function () { | |||
55 | expect(email['from'][0]['address']).equal('test-admin@localhost') | 56 | expect(email['from'][0]['address']).equal('test-admin@localhost') |
56 | expect(email['from'][0]['name']).equal('toto@example.com') | 57 | expect(email['from'][0]['name']).equal('toto@example.com') |
57 | expect(email['to'][0]['address']).equal('admin' + server.internalServerNumber + '@example.com') | 58 | expect(email['to'][0]['address']).equal('admin' + server.internalServerNumber + '@example.com') |
58 | expect(email['subject']).contains('Contact form') | 59 | expect(email['subject']).contains('my subject') |
59 | expect(email['text']).contains('my super message') | 60 | expect(email['text']).contains('my super message') |
60 | }) | 61 | }) |
61 | 62 | ||
@@ -64,6 +65,7 @@ describe('Test contact form', function () { | |||
64 | url: server.url, | 65 | url: server.url, |
65 | fromEmail: 'toto@example.com', | 66 | fromEmail: 'toto@example.com', |
66 | body: 'my super message', | 67 | body: 'my super message', |
68 | subject: 'my subject', | ||
67 | fromName: 'Super toto' | 69 | fromName: 'Super toto' |
68 | }) | 70 | }) |
69 | 71 | ||
@@ -72,6 +74,7 @@ describe('Test contact form', function () { | |||
72 | fromEmail: 'toto@example.com', | 74 | fromEmail: 'toto@example.com', |
73 | body: 'my super message', | 75 | body: 'my super message', |
74 | fromName: 'Super toto', | 76 | fromName: 'Super toto', |
77 | subject: 'my subject', | ||
75 | expectedStatus: 403 | 78 | expectedStatus: 403 |
76 | }) | 79 | }) |
77 | }) | 80 | }) |
@@ -82,8 +85,9 @@ describe('Test contact form', function () { | |||
82 | await sendContactForm({ | 85 | await sendContactForm({ |
83 | url: server.url, | 86 | url: server.url, |
84 | fromEmail: 'toto@example.com', | 87 | fromEmail: 'toto@example.com', |
85 | body: 'my super message', | 88 | fromName: 'Super toto', |
86 | fromName: 'Super toto' | 89 | subject: 'my subject', |
90 | body: 'my super message' | ||
87 | }) | 91 | }) |
88 | }) | 92 | }) |
89 | 93 | ||
diff --git a/shared/extra-utils/server/contact-form.ts b/shared/extra-utils/server/contact-form.ts index 80394cf99..e002e03dd 100644 --- a/shared/extra-utils/server/contact-form.ts +++ b/shared/extra-utils/server/contact-form.ts | |||
@@ -5,6 +5,7 @@ function sendContactForm (options: { | |||
5 | url: string, | 5 | url: string, |
6 | fromEmail: string, | 6 | fromEmail: string, |
7 | fromName: string, | 7 | fromName: string, |
8 | subject: string, | ||
8 | body: string, | 9 | body: string, |
9 | expectedStatus?: number | 10 | expectedStatus?: number |
10 | }) { | 11 | }) { |
@@ -13,6 +14,7 @@ function sendContactForm (options: { | |||
13 | const body: ContactForm = { | 14 | const body: ContactForm = { |
14 | fromEmail: options.fromEmail, | 15 | fromEmail: options.fromEmail, |
15 | fromName: options.fromName, | 16 | fromName: options.fromName, |
17 | subject: options.subject, | ||
16 | body: options.body | 18 | body: options.body |
17 | } | 19 | } |
18 | return request(options.url) | 20 | return request(options.url) |
diff --git a/shared/models/server/contact-form.model.ts b/shared/models/server/contact-form.model.ts index 0696be8b4..c23e6d1ba 100644 --- a/shared/models/server/contact-form.model.ts +++ b/shared/models/server/contact-form.model.ts | |||
@@ -1,5 +1,6 @@ | |||
1 | export interface ContactForm { | 1 | export interface ContactForm { |
2 | fromEmail: string | 2 | fromEmail: string |
3 | fromName: string | 3 | fromName: string |
4 | subject: string | ||
4 | body: string | 5 | body: string |
5 | } | 6 | } |